J2ME 中是否有可能将图像(从带有 alpha 的 png 文件加载)转换为新的透明灰度图像?
到目前为止,我只得到了 rgb 值,但没有得到 alpha。
谢谢。
编辑:是的,它应该是 32 位灰度。
我找到了解决方案,这是代码:
public Image getGrayScaleImage() {
int[] rgbData = new int[getWidth() * getHeight()];
image.getRGB(rgbData, 0, getWidth(), 0, 0, getWidth(), getHeight());
for (int x = 0; x < getWidth() * getHeight(); x++) {
rgbData[x] = getGrayScale(rgbData[x]);
}
Image grayImage = Image.createRGBImage(rgbData, getWidth(), getHeight(), true);
return grayImage;
}
private int getGrayScale(int c) {
int[] p = new int[4];
p[0] = (int) ((c & 0xFF000000) >>> 24); // Opacity level
p[1] = (int) ((c & 0x00FF0000) >>> 16); // Red level
p[2] = (int) ((c & 0x0000FF00) >>> 8); // Green level
p[3] = (int) (c & 0x000000FF); // Blue level
int nc = p[1] / 3 + p[2] / 3 + p[3] / 3;
// a little bit brighter
nc = nc / 2 + 127;
p[1] = nc;
p[2] = nc;
p[3] = nc;
int gc = (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
return gc;
}
getRGB 返回还包括 Alpha 通道的颜色值。所以我只需要更改数组中的每个值并从中创建一个图像。
我在诺基亚论坛中找到了一份有用的文档:MIDP 2.0: Working with Pixels and drawRGB()
感谢您提供有关转换为灰度的代码。但是,我注意到,在诺基亚 Series 40 设备上,此代码运行得相当慢。
有 2 个优化。主要的是删除 getGrayScale() 中的任何对象创建。目前,为每个像素创建一个数组对象。对于平均而言,比如 QVGA,显示创建了 76800 个数组对象,这是很多垃圾,并且可能会调用 GC。将 int[4] 定义为类中的字段会删除此对象创建。这里的权衡是用于该类的少量额外 RAM。
二是将宽高缓存到getGrayScaleImage()中。在某些设备上,对 getWidth() 和 getHeight() 的方法调用将在没有优化的情况下重复调用(JIT 编译器可以,但某些解释设备不行)。因此,对于 QVGA,getWidth() 和 getHeight() 将在它们之间被称为 >150000。
总之,我发现这个修改后的版本运行得更快 :-)
public Image getGrayScaleImage(Image screenshot) {
int width = getWidth();
int height = getHeight();
int screenSizeInPixels = (width * height);
int[] rgbData = new int[width * height];
image.getRGB(rgbData, 0, width, 0, 0, width, height);
for (int x = 0; x < screenSizeInPixels ; x++) {
rgbData[x] = getGrayScale(rgbData[x]);
}
Image grayImage = Image.createRGBImage(rgbData, width, height, true);
return grayImage;
}
static int[] p = new int[4];
private int getGrayScale(int c) {
p[0] = (int) ((c & 0xFF000000) >>> 24); // Opacity level
p[1] = (int) ((c & 0x00FF0000) >>> 16); // Red level
p[2] = (int) ((c & 0x0000FF00) >>> 8); // Green level
p[3] = (int) (c & 0x000000FF); // Blue level
int nc = p[1] / 3 + p[2] / 3 + p[3] / 3;
// a little bit brighter
nc = nc / 2 + 127;
p[1] = nc;
p[2] = nc;
p[3] = nc;
int gc = (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
return gc;
}
(如果您真的不想使用类数据空间,只需将 int[] 替换为四个单独的本地 int 变量,这些变量将存在于堆栈中)