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

发布于 2024-08-25 05:29:59 字数 133 浏览 13 评论 0原文

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

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

谢谢。

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

is there any possiblity in J2ME to convert an image (loaded from a png file with alpha) to a new transparent grayscale image?

Until now I only got the rgb values, but not the alpha.

Thanks.

Edit: yes, it should be 32 bit grayscale.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

绮烟 2024-09-01 05:29:59

我找到了解决方案,代码如下:

    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:使用像素和drawRGB()

I found the solution and here is the code:

    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 returns the color value that also includes the alpha channel. So I only had to change each value in the array and create an image from that.

I found a helpful document in the nokia forum: MIDP 2.0: Working with Pixels and drawRGB()

深者入戏 2024-09-01 05:29:59

感谢您提供有关转换为灰度的代码。然而,我注意到,在诺基亚 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[] ,这些变量将存在于堆栈中)

Thanks for the code on converting to greyscale. However, I noticed that, on Nokia Series 40 devices, this code runs rather slowly.

There are 2 optimisations . The main one is to remove any object creation in getGrayScale(). Currently , an array object is created for every pixel . For an average ,say QVGA, display that is 76800 array objects created, which is a lot of garbage, and will probably invoke GC. Defining the int[4] as a field in the class removes this object creation. The trade off here is a small amount of additional RAM used for the class.

The second is to cache the width and height into getGrayScaleImage(). On some devices, the method calls to getWidth() and getHeight() will be repeatedly called without optimisations ( a JIT compiler will be OK but some interpreted devices not ). So , again for QVGA, the getWidth() and getHeight() will be called some >150000 between them.

In all, I found this modified version ran much quicker :-)

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;
}

( If you really don't want to use class data space, just replace the int[] with four separate local int variables which would live on the stack)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文