I have a .PNG image with a transparent background and a drawing in it with a black color, how could I change the "black drawing color" in this image to any color i want programmatically; using rim 4.5 API ? THANKS IN ADVANCE ....
Asked
Active
Viewed 2,582 times
3 Answers
2
I found the solution, here it is for those who are interested.
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;
}

Ashraf Bashir
- 9,686
- 15
- 57
- 82
-
Yes it will work, but it won't change any colours that are even slightly off-black, meaning any image which is aliased will end up looking rather ugly. – funkybro Feb 15 '10 at 09:12
1
You can parse the image RGBs searching for the black color and replace it with whatever color you desire.

Ali El-sayed Ali
- 451
- 4
- 14
1
You can read your PNG image to byte array and edit palette chunk. This method is suitable only for PNG-8 images. Here is my code:
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);
}
}

Pavel Alexeev
- 6,026
- 4
- 43
- 51
-
could you explain why you are incrementing the offset? And what is the purpose of the offset parameter? – S-K' Jan 24 '13 at 16:08
-
'offset' is just a current position in a file - we read the stream and write it to the array at current position. But this code is 3 years old – now it seems to me that it would be better to read the whole file into array and then edit this array :) – Pavel Alexeev Jan 24 '13 at 16:21