携帯アプリ開発のツボ〜画像をダウンロードする〜
開発チームの蝦名です。
先週末に釣りに行ってきました。
釣りを始めてから4ヶ月。
ず〜っとボーズな日々だったのですが、
なんと遂に1匹釣り上げました!
でも、小さなウグイだったので誰にも自慢できません。。。
ま、ここから私のフィッシング・ライフが始まるということにして
次はデカい獲物を狙っていきましょう!
(デカいウグイを釣ったりして・・・)
■携帯アプリ開発のツボ〜画像をダウンロードする〜
今週は、画像をダウンロードしてみましょう。
近頃ではメガアプリなんて規格がでてきましたが、携帯電話ではアプリ容量が非常に制限されてきました。
今後も様々な事情でアプリの容量には制限が付きまとうでしょう。
アプリ本体であるJARファイルを出来るだけコンパクトにすることがとても大事になります。
そこで、実際のプログラム以外の部分、特にサイズが大きくなりがちな画像データをアプリの外に追い出すのはとても有効です。
今回は、その第一歩として画像をダウンロードする部分を考えてみましょう。
基本部分は前回の「通信する」の回と同じになります。
//画像ダウンロード HttpConnection con = null; InputStream is = null; try { String url = IApplication.getCurrentApp().getSourceURL() + "logo.gif"; con = (HttpConnection)Connector.open(url, Connector.READ, true); con.setRequestMethod(HttpConnection.GET); con.connect(); is = con.openInputStream(); byte [] buf = new byte[2048]; //※1 int readsize = is.read(buf); is.close(); con.close(); MediaImage mi = MediaManager.getImage(buf); //※2 mi.use(); imgGrph = mi.getImage(); } catch (Exception e) { try { if (is != null) is.close(); if (con != null) con.close(); } catch (Exception e2) { } }
はい、ほとんど前回の文字情報を受取る部分と同じですね?
ポイントは2つあります。
1つめのポイントは、※1で示した行で確保しているバッファのサイズです。
このサイズには画像データが収まるようなサイズを指定してください。
もしも、どんなデータをダウンロードするのか事前には分からない場合には、次の行で得ることが出来るreadsizeを参照して、改めてバッファを確保する方法もあります。
2つめのポイントは、※2から始まる部分です。
前回の文字情報ではStringクラスを利用して文字列を作成しましたが、今回はMediaManagerクラスとMediaImageクラスを利用してダウンロードしたバイト情報から画像を作成しています。
今回は、はやしさんの為に大サービスでソースを掲載しましょう。
HelloClass.java
import com.nttdocomo.ui.*; public class HelloClass extends IApplication { HelloCanvas hc; public void start() { // アプリ起動時の処理 hc = new HelloCanvas(); Display.setCurrent(hc); hc.mainloop(); } }
HelloCanvas.java
import java.io.IOException; import java.io.InputStream; import javax.microedition.io.Connector; import com.nttdocomo.ui.*; import com.nttdocomo.io.*; import com.nttdocomo.opt.ui.*; public class HelloCanvas extends Canvas { Image imgGrph = null; int counter = 0; //処理の進行を管理するカウンター int srcRatio = 0; //描画元のピクセル色の割合 int dstRatio = 0; //描画先のピクセル色の割合 //表示メッセージ String message = ""; public HelloCanvas() { // コンストラクター super(); try { //前回使用した画像を読み込む部分 //画像を読み込む //MediaImage mi = MediaManager.getImage("resource:///logo.gif"); //mi.use(); //imgGrph = mi.getImage(); } catch (Exception e) { } } public void paint(Graphics arg0) { Graphics2 g = (Graphics2)arg0; //Graphics2オブジェクトへキャスト g.lock(); //ダブルバッファリング //背景 if (imgGrph != null) { //画像を描画 g.drawImage(imgGrph, 0, 0); } else { //画面をクリア g.clearRect(0, 0, getWidth(), getHeight()); } //半透明マスク g.setRenderMode(Graphics2.OP_ADD, 0, dstRatio); g.setColor(Graphics2.getColorOfName(Graphics2.BLACK)); g.fillRect(0, 0, 240, 240); g.setRenderMode(Graphics2.OP_REPL, 255, 255); //影付きメッセージを画面左上の方に書く g.setColor(Graphics2.getColorOfName(Graphics2.BLACK)); g.drawString(message, 20, 20); g.setColor(Graphics2.getColorOfName(Graphics2.WHITE)); g.drawString(message, 19, 19); g.unlock(true); //ダブルバッファリング終了 } static final int STEPS = 15; //ループ処理の基準値 public void mainloop() { Graphics2 g = (Graphics2)getGraphics(); //Graphics2オブジェクト try { //画面描画 message = "画像ダウンロード中"; paint(g); //画像ダウンロード HttpConnection con = null; InputStream is = null; try { String url = IApplication.getCurrentApp().getSourceURL() + "logo.gif"; con = (HttpConnection)Connector.open(url, Connector.READ, true); con.setRequestMethod(HttpConnection.GET); con.connect(); is = con.openInputStream(); byte [] buf = new byte[2048]; int readsize = is.read(buf); is.close(); con.close(); MediaImage mi = MediaManager.getImage(buf); mi.use(); imgGrph = mi.getImage(); } catch (Exception e) { try { if (is != null) is.close(); if (con != null) con.close(); } catch (Exception e2) { } } message = "画像ダウンロード完了"; paint(g); //メインループ while (true) { //始めの基準ステップはだんだん明るくする if ( 0 <= counter && counter < STEPS) dstRatio = 255 * counter / STEPS; //次の基準ステップは明るいままキープ if (STEPS <= counter && counter < STEPS*2) dstRatio = 255; //次の基準ステップはだんだん暗くする if (STEPS*2 <= counter && counter < STEPS*3) dstRatio = 255 * (STEPS*3 - counter) / STEPS; //次の基準ステップは暗いままキープ if (STEPS*3 <= counter && counter < STEPS*4) dstRatio = 0; //始めに戻す if (STEPS*4 <= counter) counter = 0; //画面描画 paint(g); //ループ時間調整 Thread.sleep(66); counter++; } } catch (Exception e) { } } //イベント処理ハンドラ public void processEvent(int type, int para) { if (type == Display.KEY_PRESSED_EVENT) //キー押しイベントだったら { switch (para) { case Display.KEY_UP: message = "UP"; break; case Display.KEY_DOWN: message = "DOWN"; break; case Display.KEY_LEFT: message = "LEFT"; break; case Display.KEY_RIGHT: message = "RIGHT"; break; /* // 前回使用した文字情報をダウンロードする部分 case Display.KEY_SELECT: { HttpConnection con = null; InputStream is = null; try { String url = IApplication.getCurrentApp().getSourceURL() + "text.txt"; message = url; con = (HttpConnection)Connector.open(url, Connector.READ, true); con.setRequestMethod(HttpConnection.GET); con.connect(); is = con.openInputStream(); byte [] buf = new byte[256]; int readsize = is.read(buf); is.close(); con.close(); message = new String(buf); } catch (Exception e) { try { if (is != null) is.close(); if (con != null) con.close(); } catch (Exception e2) { } } } break; */ } repaint(); } } }
アプリを動かす前に、logo.gifをサーバーにアップするのを忘れないでくださいね。
では、また来週。