J2ME:将透明PNG图像转换为灰度图像

时间:2010-03-09 19:47:44

标签: image java-me midp grayscale lcdui

J2ME中是否有可能将图像(从带有alpha的png文件加载)转换为新的透明灰度图像?

到目前为止,我只获得了rgb值,但没有得到alpha。

感谢。

编辑:是的,它应该是32位灰度。

2 个答案:

答案 0 :(得分:4)

我找到了解决方案,这里是代码:

    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()

答案 1 :(得分:0)

感谢转换为灰度的代码。但是,我注意到,在诺基亚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变量,这些变量将存在于堆栈中)