Nanashi-softプログラマ専用BD-J


◇BD-J-ピクセルデータから画像生成-

Javaには VRAMの概念がありません
それだとプログラミングができない人がいます(私とか)
画面にドットを打つ方法を説明します

○ピクセルデータのフォーマット

先頭から8ビットで、ARGBです
Aは 0側が透明ですで 8ビット深度です
以上(ぉ

これで分からない人は、そもそもこのページ読む必要無いので飛ばして下さい('-'*)

○ピクセルデータをイメージデータに変換

Javaでは、Image形式にしなければ画面表示が行えませんので、createImageします
色の順番とかわかり易いようにして書いておきます

public void paint(Graphics g){
  int w= 640;
  int h= 480;
  int pix[]= new int[w * h];
  int index = 0;
  int red,green,blue;
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      red= 0;
      green= 0;
      blue= 255;
      pix[index++] = (255 << 24) | (red << 16) | (green << 8) | blue;
    }
  }
  Image img= createImage(new MemoryImageSource(w, h, pix, 0, w));

  MediaTracker tracker= new MediaTracker(this);
  tracker.addImage(img, 0);
  try{  tracker.waitForAll();  }catch(Exception e){}

  g.drawImage(img, 0, 0, this);
}

αをシフトで書きましたが、int型は signedなので、右シフトする場合は十分注意して下さい
Javaには右大なり3つの演算子があるようです
C言語だと (unsigned char)255 >> 1のところを、Javaは 255 >>> 1; ではないかと思われます
(255 & 0x7f) >> 1 とかがいいのかな?

○画像の明るさを半減する

画像を読み込んで、RGBそれぞれ半分の明るさにしてみます
サンプルですので、これ自体に深い意味はありません
createImageの反対は PixelGrabberです

public void paint(Graphics g){
    //イメージ読み込み
    Image img= Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("xxx.jpg"));
    MediaTracker tracker= new MediaTracker(this);
    tracker.addImage(img, 0);
    try{  tracker.waitForAll();  }catch(Exception e){}
    int w= img.getWidth(null);
    int h= img.getHeight(null);;

    //ピクセルデータに戻す
    int[] pix= new int[w * h];
    PixelGrabber pg= new PixelGrabber(img, 0, 0, w, h, pix, 0, w);
    try{  pg.grabPixels();  }catch(Exception e){}

    //明るさを半減
    int red,green,blue;
    for(int index=0; index < pix.length; index++){
      //RGB値取得
      red= (pix[index] & 0xff0000) >> 16;
      green= (pix[index] & 0xff00) >> 8;
      blue= pix[index] & 0xff;
      //半分にする(端数切捨て)
      red= red >> 1;
      green= green >> 1;
      blue= blue >> 1;
      //元のintに戻す
      pix[index] = (255 << 24) | (red << 16) | (green << 8) | blue;
    }

    //イメージに戻す
    Image img2= createImage(new MemoryImageSource(w, h, pix, 0, w));
    tracker= new MediaTracker(this);
    tracker.addImage(img2, 0);
    try{  tracker.waitForAll();  }catch(Exception e){}

    //描画
    g.drawImage(img2, 0, 0, this);
}


やってみればわかる事ですが、paintに直接こんな事を書くと異様に遅いです
なぜなら、何もしていなくても paintメソッドは毎秒数十回来ているからです
きちんと、自分で FPS管理して描画しましょう(そういう事する人しかこのページ読む意味無いわけですが)

高速化の為に、演算は intのまま行うのも手です
例えば、上の例だと

    //明るさを半減
    for(int index=0; index < pix.length; index++){
      pix[index]= ((pix[index] & 0x00fefefe) >> 1) | 0xff000000;
    }

こんな感じにすると、変数も演算量も減りますよね?(そんな事は百も承知と言う人しかこのページ(以下略))


以上、全ての説明は BD-Jに限った話では無く、Javaの説明になっちゃっています(*'-')


TOPプログラマ専用BD-J

Melonbooks DL