2007/04/22(日) [n年前の日記]
#3 [iappli] PaletteImage について実験中
Palette から getEntry() で取り出した int を Integer.toHexString() で16進数表示したら、

なんとかなりそうな予感。後は画像のロード部分に処理を追加 or 別途ロード処理を作成、かしら。実機上で動かした際のヒープサイズや描画処理速度が懸念されそうではあるけど。
00ffffffff 00ffff0000 00ff00ff00 00ff0000ff 00ff010203 00ff800000 00ff008000 00ff000080 00ff00ffff 00ffff00ff 00ffffff00こんな感じの値に。おそらくは、
((謎値 & 0x0ff) << 24) | ((R & 0x0ff) << 16) | ((G & 0x0ff) << 16) | (B & 0x0ff)という感じ? 謎の値で 0x0ff が入ってるのが気になるけれど。もしかすると不透明度の情報なのかもしれない。ということでそんな感じに推測して実験ソースを。
/**
* PalettedImage の表示テスト
*/
import java.io.InputStream;
import javax.microedition.io.Connector;
import com.nttdocomo.io.ConnectionException;
import com.nttdocomo.ui.Canvas;
import com.nttdocomo.ui.Dialog;
import com.nttdocomo.ui.Display;
import com.nttdocomo.ui.Graphics;
import com.nttdocomo.ui.IApplication;
import com.nttdocomo.ui.Image;
import com.nttdocomo.ui.MediaImage;
import com.nttdocomo.ui.MediaManager;
import com.nttdocomo.ui.Palette;
import com.nttdocomo.ui.PalettedImage;
import com.nttdocomo.ui.PhoneSystem;
public class TestPalettedImage extends IApplication {
Main m = new Main();
public void start() {
Display.setCurrent(m);
m.exec();
}
}
final class Main extends Canvas {
static final int FPS = 20;
static final int SLEEP_VALUE = 1000 / FPS;
static final int SCR_W = 240;
static final int SCR_H = 240;
private Graphics g = getGraphics();
private int waitTime;
private long getTime;
private int frameCounter;
private int rootStep;
private Image bgimg;
private PalettedImage palimg;
private Palette[] pal = new Palette[5 * 5];
private int btnStsInterrupt;
// コンストラクタ
public Main() {
System.gc();
}
// メイン
public void exec() {
waitTime = SLEEP_VALUE; // フレーム間隔
rootStep = 0;
// バックライトON
PhoneSystem.setAttribute(PhoneSystem.DEV_BACKLIGHT, PhoneSystem.ATTR_BACKLIGHT_ON);
getTime = System.currentTimeMillis();
// メインループ
while (true) {
try {
switch (rootStep) {
case 0 :
// init
{
// 背景画像をロード
MediaImage image = MediaManager.getImage("resource:///3.gif");
try {
image.use();
bgimg = image.getImage();
} catch (ConnectionException e) {
image = null;
displayDialog(Dialog.DIALOG_ERROR, "実行エラー", "BGイメージロード失敗。" + e);
}
// パレットを変える画像をロード
try {
// Connection con=Connector.open("resource:///testimg.gif",Connector.READ);
// InputConnection incon=(InputConnection)con;
// InputStream in = incon.openInputStream();
InputStream in = Connector.openInputStream("resource:///2.gif");
// パレットを設定できるイメージを生成
palimg = PalettedImage.createPalettedImage(in);
in.close();
} catch (Exception e) {
displayDialog(Dialog.DIALOG_ERROR, "Error", "パレットイメージロード失敗。" + e);
}
// パレットを取得
Palette p = palimg.getPalette();
// 色数取得
int colnum = p.getEntryCount();
// パレット値を表示してみる
for (int i = 0; i < p.getEntryCount(); i++) {
int argb = p.getEntry(i);
String s = "0000000000000000" + Integer.toHexString(argb);
String sb = s.substring(s.length() - 16);
System.out.println(sb);
}
// 変化させるためのパレットオブジェクトを確保
for (int i = 0; i < pal.length; i++) {
pal[i] = new Palette(colnum);
}
// 変化させるためのパレットを作成
for (int c = 0; c < pal.length; c++) {
int v = c * 256 / (5 * 5);
for (int i = 0; i < p.getEntryCount(); i++) {
int argb = p.getEntry(i);
int a = (argb >> 24) & 0x0ff;
int r = (argb >> 16) & 0x0ff;
int g = (argb >> 8) & 0x0ff;
int b = argb & 0x0ff;
r = r * (256 - v) / 256;
g = g * (256 - v) / 256;
b = b * (256 - v) / 256;
argb = Graphics.getColorOfRGB(r, g, b, a);
pal[c].setEntry(i, argb);
}
}
rootStep++;
}
break;
case 1 :
// draw
{
g.lock();
// BG 描画
g.drawImage(bgimg, 0, 0);
{
int w = palimg.getWidth();
int h = palimg.getHeight();
int idx = 0;
for (int y = 0; y < 5; y++) {
for (int x = 0; x < 5; x++) {
int dx = 16 + (w + 8) * x;
int dy = 16 + (h + 8) * y;
// パレットを変える
palimg.setPalette(pal[idx]);
// 描画
g.drawImage(palimg, dx, dy);
idx++;
}
}
}
g.unlock(true);
}
break;
}
System.gc();
while (System.currentTimeMillis() < getTime + waitTime)
Thread.yield();
getTime = System.currentTimeMillis();
frameCounter++;
} catch (Exception e) {
displayDialog(Dialog.DIALOG_ERROR, "実行エラー", "処理中に問題発生。" + e + " rootStep=" + rootStep);
}
}
}
// 画面描画
public void paint(Graphics g) {
}
// イベント通知処理
public void processEvent(int a_type, int a_param) {
if (a_type == Display.KEY_PRESSED_EVENT) btnStsInterrupt |= (0x01 << a_param);
}
// エラー時のダイアログ表示
public void displayDialog(int type, String title, String str) {
Dialog d = new Dialog(type, title);
d.setText(str);
d.show();
IApplication.getCurrentApp().terminate();
}
}

なんとかなりそうな予感。後は画像のロード部分に処理を追加 or 別途ロード処理を作成、かしら。実機上で動かした際のヒープサイズや描画処理速度が懸念されそうではあるけど。
◎ 2007/04/23追加。 :
上のソースは問題ありな予感。本番用ソースに同じような記述をしたら色がおかしくなった。
[ ツッコむ ]
以上です。