3

I am trying to convert MagickImage to SWT.ImageDate because former library provides API that scale images much better with smooth edges, better interpolation and preserving transparency.

This is my test image (2x2 pixel PNG file): blue pixel has transparency value 127

Blue pixel has transparency value of 127

Here is sample code I use to convert:

ImageInfo ii = new ImageInfo("img/test.png");
MagickImage mi = new MagickImage(ii);
Point p = new Point(mi.getDimension().width, mi.getDimension().height);
int blobSize = p.x * p.y;
byte[] dataBlob = new byte[blobSize * 4];
byte[] alphaDataBlob = new byte[blobSize];
PixelPacket temp = null;
int blobpos = 0;
int alphapos = 0;
for(int row=0; row<p.y; row++) {
    for (int col = 0; col < p.x; col++) {
        temp = mi.getOnePixel(col, row);
        alphapos = (row * p.x) + col;
        blobpos = 4 * ((row * p.x) + col);
        dataBlob[blobpos + 1] = (byte)(temp.getRed() & 0xFF);
        dataBlob[blobpos + 2] = (byte)(temp.getGreen() & 0xFF);
        dataBlob[blobpos + 3] = (byte)(temp.getBlue() & 0xFF);
        alphaDataBlob[alphapos] = (byte)(0xFF - (temp.getOpacity() & 0xFF));
    }
}
ImageData imageData = new ImageData(p.x, p.y, 24, new PaletteData(0xFF0000, 0x00FF00 , 0x0000FF));
imageData.data = dataBlob;
imageData.alphaData = alphaDataBlob;
ImageLoader imageLoader = new ImageLoader();
imageLoader.data = new ImageData[] {imageData};
imageLoader.save("img/result.png", SWT.IMAGE_PNG);

Result of this conversion is: enter image description here

Fourth pixel has now 255 transparency value and colours are odd.

When I read test.png file using SWT api imageData fields: data, alphadata and color masks are the same as my custom created imageData but saved images are different.

I changes colour mask values in PaletteData but with no good result. Maybe someone know how to do this correctly.

4

1 回答 1

1

The color depth of 24 does not fit with the layout of dataBlob, whoch has 4 bytes per pixel.

You can either change the ImageData constructor call to

ImageData imageData = new ImageData(p.x, p.y, 32, new PaletteData(0xFF0000, 0x00FF00, 0x0000FF));

or store 3 bytes per pixel:

blobpos = 3 * ((row * p.x) + col);
dataBlob[blobpos + 0] = (byte)(temp.getRed() & 0xFF);
dataBlob[blobpos + 1] = (byte)(temp.getGreen() & 0xFF);
dataBlob[blobpos + 2] = (byte)(temp.getBlue() & 0xFF);

Both will work.

于 2016-01-12T17:07:51.547 回答