【问题标题】:how to change a color in an image programmatically?如何以编程方式更改图像中的颜色?
【发布时间】:2011-01-16 15:52:01
【问题描述】:

我有一个带有透明背景的 .PNG 图像和一个黑色的绘图,我怎么能以编程方式将此图像中的“黑色绘图颜色”更改为我想要的任何颜色;使用 rim 4.5 API? 提前致谢....

【问题讨论】:

    标签: blackberry java-me colors rim-4.5 blackberry-os-v4.5


    【解决方案1】:

    我找到了解决方案,这里是给有兴趣的人的。

    Bitmap colorImage(Bitmap image, int color) {
        int[] rgbData= new int[image.getWidth() * image.getHeight()];
        image.getARGB(rgbData, 
                      0, 
                      image.getWidth(), 
                      0, 
                      0, 
                      image.getWidth(), 
                      image.getHeight());
        for (int i = 0; i < rgbData.length; i++) {
            int alpha = 0xFF000000 & rgbData[i];
            if((rgbData[i] & 0x00FFFFFF) == 0x00000000)
                rgbData[i]= alpha | color;
        }
        image.setARGB(rgbData,
                      0, 
                      image.getWidth(),
                      0,
                      0,
                      image.getWidth(),
                      image.getHeight());
        return image;
    }
    

    【讨论】:

    • 是的,它会起作用,但它不会改变任何颜色,甚至是稍微偏黑的颜色,这意味着任何混叠的图像最终都会看起来相当难看。
    【解决方案2】:

    您可以解析图像 RGB,搜索黑色并将其替换为您想要的任何颜色。

    【讨论】:

      【解决方案3】:

      您可以将 PNG 图像读取到字节数组并编辑调色板块。 此方法仅适用于 PNG-8 图像。 这是我的代码:

      public static Image createImage(String filename) throws Throwable { DataInputStream dis = null; InputStream is = null; try { is = new Object().getClass().getResourceAsStream(filename); dis = new DataInputStream(is); int pngLength = dis.available(); byte[] png = new byte[pngLength]; int offset = 0; dis.read(png, offset, 4); offset += 4; //‰PNG dis.read(png, offset, 4); offset += 4; //.... while (true) { //length dis.read(png, offset, 4); offset += 4; int length = (png[offset-1]&0xFF) | ((png[offset-2]&0xFF)<<8) | ((png[offset-3]&0xFF)<<16) | ((png[offset-4]&0xFF)<<24); //chunk type dis.read(png, offset, 4); offset += 4; int type = (png[offset-1]&0xFF) | ((png[offset-2]&0xFF)<<8) | ((png[offset-3]&0xFF)<<16) | ((png[offset-4]&0xFF)<<24); //chunk data for (int i=0; i<length; i++) { dis.read(png, offset, 1); offset += 1; } //CRC dis.read(png, offset, 4); offset += 4; int crc = (png[offset-1]&0xFF) | ((png[offset-2]&0xFF)<<8) | ((png[offset-3]&0xFF)<<16) | ((png[offset-4]&0xFF)<<24); if (type == 0x504C5445) { //'PLTE' int CRCStart = offset-4; int PLTEStart = offset-4-length; //modify PLTE chunk for (int i=PLTEStart; i<PLTEStart+length; i+=3) { png[i+0] = ... png[i+1] = ... png[i+2] = ... } int newCRC = crc(png, PLTEStart-4, length+4); png[CRCStart+0] = (byte)(newCRC>>24); png[CRCStart+1] = (byte)(newCRC>>16); png[CRCStart+2] = (byte)(newCRC>>8); png[CRCStart+3] = (byte)(newCRC); } if (offset >= pngLength) break; } return Image.createImage(png, 0, pngLength); } catch (Throwable e) { throw e; } finally { MainCanvas.closeInputStream(dis); MainCanvas.closeInputStream(is); } }

      【讨论】:

      • 您能解释一下为什么要增加偏移量吗?而offset参数的作用是什么?
      • 'offset' 只是文件中的当前位置 - 我们读取流并将其写入当前位置的数组。但是这段代码已经有 3 年历史了——现在在我看来,将整个文件读入数组然后编辑这个数组会更好:)
      猜你喜欢
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 2016-07-03
      • 1970-01-01
      • 2015-12-06
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多