6

aparapi を使用して、Buddhabrot フラクタル ジェネレーターを作成しています。その OpenCL 部分を機能させて、各ピクセルを表す 1 次元配列を作成しました。最終的な画像の寸法を最終的な int として取得し、その配列内の任意の点のインデックスを取得するコードを記述しました。これを画像として保存したいのですが、TYPE_USHORT_GRAY で BufferedImage を使用しようとしています。これが私がこれまでに持っているものです:

    BufferedImage image=new BufferedImage(VERTICAL_PIXELS, HORIZONTAL_PIXELS, BufferedImage.TYPE_USHORT_GRAY);
    for(int i=0; i<VERTICAL_PIXELS; i++)
        for(int k=0; k<HORIZONTAL_PIXELS; k++)
            image.setRGB(k, i, normalized[getArrayIndex(k,i,HORIZONTAL_PIXELS)]);

問題は、RGB を何に設定すればよいか分からないことです。私は何をする必要がありますか?

4

2 に答える 2

7

ここでの問題はsetRGB()、0xRRGGBB カラー値が必要なことです。BufferedImage は、データがどのような形式で保存されているかに関係なく、画像が RGB であるかのように見せかけます。DataBufferShort実際には( を使用して)内部getTile(0, 0).getDataBuffer()にアクセスできますが、どのように配置されているかを理解するのは難しい場合があります。

ピクセルが既に にある場合short[]、より簡単な解決策は、それらを にコピーするint[]代わりににコピーすることMemoryImageSourceです。

int[] buffer = /* pixels */;

ColorModel model = new ComponentColorModel(
   ColorSpace.getInstance(ColorSpace.CS_GRAY), new int[] { 16 }, 
   false, true, Transparency.OPAQUE, DataBuffer.TYPE_USHORT);

Image image = Toolkit.getDefaultToolkit().createImage(
   new MemoryImageSource(VERTICAL_PIXELS, HORIZONTAL_PIXELS, 
                         model, buffer, 0, VERTICAL_PIXELS));

このアプローチの利点は、基になるピクセル配列を制御できることです。その配列に変更を加えて を呼び出すと、ライブで更新さnewPixels()れます。MemoryImageSourceまた、グレースケール以外の独自のパレットを定義する完全な機能も提供します。

int[] cmap = new int[65536];
for(int i = 0; i < 65536; ++i) {

    cmap[i] = (((i % 10000) * 256 / 10000) << 16) 
            | (((i % 20000) * 256 / 20000) << 8)
            | (((i % 40000) * 256 / 40000) << 0);
}
ColorModel model = new IndexColorModel(16, 65536, cmap, 0, false, -1, DataBuffer.TYPE_USHORT);

画面に画像を表示するだけの場合、このアプローチはうまく機能します。

JFrame frame = new JFrame();
frame.getContentPane().add(new JLabel(new ImageIcon(image)));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

ただし、それをファイルに書き出して、1 ピクセルあたり 1 ショート フォーマットを保持したい場合 (たとえば、Matlab にロードする場合) は、うまくいきません。あなたができる最善の方法は、それを にペイントしてBufferedImageで保存することImageIOです。これは RGB として保存されます。

最後にがどうしても必要な場合はBufferedImage、別の方法として、自分でカラー パレットを適用し、RGB 値を計算してから、それらを画像にコピーします。

short[] data = /* your data */;
int[] cmap = /* as above */;
int[] rgb = new int[data.length];

for(int i = i; i < rgb.length; ++i) {
   rgb[i] = cmap[data[i]];
}

BufferedImage image = new BufferedImage(
   VERTICAL_PIXELS, HORIZONTAL_PIXELS, 
   BufferedImage.TYPE_INT_RGB);

image.setRGB(0, 0, VERTICAL_PIXELS, HORIZONTAL_PIXELS,
   pixels, 0, VERTICAL_PIXELS);
于 2012-01-07T00:01:27.583 に答える
3

BufferedImage参考までに、この例では、2 つの異なる型が同じ 16 ビット データをどのように解釈するかを示しています。画像にマウスを合わせると、ピクセル値が表示されます。

補遺: interpretsetRGB()という言葉について詳しく説明するために、 は指定された で指定された値に最も近いものを見つけようとすることに注意してくださいColorModel

BufferedImageTest

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;

/** @see http://stackoverflow.com/questions/8765004 */
public class BufferedImageTest extends JPanel {

    private static final int SIZE = 256;
    private static final Random r = new Random();
    private final BufferedImage image;

    public BufferedImageTest(int type) {
        image = new BufferedImage(SIZE, SIZE, type);
        this.setPreferredSize(new Dimension(SIZE, SIZE));
        for (int row = 0; row < SIZE; row++) {
            for (int col = 0; col < SIZE; col++) {
                image.setRGB(col, row, 0xff00 << 16 | row << 8 | col);
            }
        }
        this.addMouseMotionListener(new MouseAdapter() {

            @Override
            public void mouseMoved(MouseEvent e) {
                Point p = e.getPoint();
                int x = p.x * SIZE / getWidth();
                int y = p.y * SIZE / getHeight();
                int c = image.getRGB(x, y);
                setToolTipText(x + "," + y + ": "
                    + String.format("%08X", c));
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g) {
        g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
    }

    static private void display() {
        JFrame f = new JFrame("BufferedImageTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new GridLayout(1, 0));
        f.add(new BufferedImageTest(BufferedImage.TYPE_INT_ARGB));
        f.add(new BufferedImageTest(BufferedImage.TYPE_USHORT_GRAY));
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                display();
            }
        });
    }
}
于 2012-01-07T03:39:12.360 に答える