2008-07-11

Picasa用アップローダーiアプリ

906シリーズからiモードにファイルのアップロード機能が追加になったので、きっとgoogleが
モバイル版Picasaにアップロード機能をつけてくれるだろう。
でも自分の携帯電話は905シリーズなので、例えそのようなサービスが提供されても使えないので、前回作ったPicasa Ploxy Server を中継して写真をアップロードするiアプリを作成した。

以下はそのソースコード。



import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.microedition.io.Connector;

import com.nttdocomo.io.ConnectionException;
import com.nttdocomo.io.HttpConnection;
import com.nttdocomo.system.ImageStore;
import com.nttdocomo.system.InterruptedOperationException;
import com.nttdocomo.system.StoreException;
import com.nttdocomo.ui.Canvas;
import com.nttdocomo.ui.Dialog;
import com.nttdocomo.ui.Display;
import com.nttdocomo.ui.Frame;
import com.nttdocomo.ui.Graphics;
import com.nttdocomo.ui.IApplication;
import com.nttdocomo.ui.Image;
import com.nttdocomo.ui.MediaImage;


public class iPicasa extends IApplication {
public void start() {
iPicasaCanvas canvas = new iPicasaCanvas();
Display.setCurrent(canvas);
}

class iPicasaCanvas extends Canvas {
String proxyUrl = null;
int id = -1;
MediaImage media = null;
Image image = null;

public iPicasaCanvas(){
proxyUrl = getArgs()[0];
setSoftLabel(Frame.SOFT_KEY_1,"終了");
setSoftLabel(Frame.SOFT_KEY_2,"選択");
}

private byte [] post(String url, byte [] data) throws IOException {
HttpConnection conn = null;
OutputStream os = null;
InputStream is = null;
try {
conn = (HttpConnection)(Connector.open(url, Connector.READ_WRITE, true));
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

os = conn.openOutputStream();
os.write(data);
os.close();

conn.connect();

is = conn.openInputStream();

ByteArrayOutputStream response = new ByteArrayOutputStream();
byte buff[] = new byte[1024];
int len;
while((len = is.read(buff)) != -1) {
response.write(buff, 0, len);
}
is.close();

return response.toByteArray();

} finally {
try{
if (os != null) os.close();
if (is != null) is.close();
if (conn != null) conn.close();
} catch (IOException ioe) {}
}
}

private void selectImage() throws InterruptedOperationException, ConnectionException {
ImageStore imageStore = ImageStore.selectEntry();
if (imageStore == null) {
return;
}
id = imageStore.getId();
media = imageStore.getImage();
media.use();
image = media.getImage();

setSoftLabel(Frame.SOFT_KEY_2,"登録");

repaint();
}

private void cretaePhoto() throws IOException, StoreException {
InputStream in = ImageStore.getEntry(id).getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte buff[] = new byte[1024];
int len;
while((len = in.read(buff)) != -1) {
out.write(buff, 0, len);
}
in.close();

String response = new String(post(proxyUrl+"/createPhoto.do", out.toByteArray()));
if (!"OK".equals(response)) {
Dialog dlg = new Dialog(Dialog.BUTTON_OK, "画像登録");
dlg.setText("失敗しました");
dlg.show();
return;
}

Dialog dlg = new Dialog(Dialog.BUTTON_OK, "画像登録");
dlg.setText("登録しました");
dlg.show();

id = -1;
media.unuse();
media.dispose();
image = null;

setSoftLabel(Frame.SOFT_KEY_2,"選択");

repaint();
}

public void processEvent(int type, int param) {
try {
if (type == Display.KEY_RELEASED_EVENT) {
switch(param) {
case Display.KEY_SOFT1:
terminate();
break;
case Display.KEY_SOFT2:
if (id == -1) {
selectImage();
} else {
cretaePhoto();
}
break;
}
}
} catch (Exception e) {
Dialog dlg = new Dialog(Dialog.BUTTON_OK, "error");
dlg.setText(e.toString());
dlg.show();

e.printStackTrace();
}
}

public void paint(Graphics g) {
g.lock();
g.setColor(Graphics.getColorOfRGB(0xFF, 0xFF, 0xFF));
g.fillRect(0, 0, Display.getWidth(), Display.getHeight());
if (image != null) {
float scaleX = (float) Display.getWidth() / (float)image.getWidth();
float scaleY = (float) Display.getHeight() / (float)image.getHeight();

float scale = (scaleX < scaleY) ? scaleX : scaleY;
if (scale > 1.0f) {
scale = 1.0f;
}

int width = (int)(image.getWidth() * scale);
int height = (int)(image.getHeight() * scale);
int dx = (Display.getWidth()-width)/2;
int dy = (Display.getHeight()-height)/2;

g.drawScaledImage(image, dx, dy, width, height, 0, 0, image.getWidth(), image.getHeight());
}
g.unlock(true);
}
}
}


iアプリの通信機能はグローバルなドメインが必要なので、このiアプリの利用には、残念ながらドメインを持っている人でなければ使えない。
なので私は無料のダイナミックDNSを使ってドメインを取得、試験してみた。

で、問題発見。

iアプリのPOSTは1回の通信あたり80Kバイトまでに制限されていたことを忘れており、あまり大きな画像がアップロードできない。
今の携帯携帯カメラはメガピクセル。
これは利用に当たって問題なので、いずれ修正したい。