Вы можете прочитать ваше изображение 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);
}
}