Is there a fast way in Java to replace all instances in a bitmap of certain colors with other colors?
The image I am working with is a single very large 5616 x 2160 24bit non-transparent unindexed bitmap, although the pixel values of this bitmap will vary.
This is the code I am using at the moment, but it is much too slow: http://pastebin.com/UjgwgB0V
public class DisplayImage extends JFrame {
public DisplayImage(boolean resize, boolean mapCountries) throws IOException {
super("Province Map");
File mapProvinceFile = new File("map\\provinces.bmp");
BufferedImage mapProvinceImage = ImageIO.read(mapProvinceFile);
byte[] pixels = (byte[])mapProvinceImage.getRaster().getDataElements(0, 0, mapProvinceImage.getWidth(), mapProvinceImage.getHeight(), null);
if (mapCountries) {
for (int i = 0; i < Victoria2Stats.provinceDefinitionArray.size(); i++) {
for (int p = 0; p < pixels.length-3; p = p + 3) {
if ((byte)Victoria2Stats.provinceDefinitionArray.get(i).rgb[0] == pixels[p]) {
if ((byte)Victoria2Stats.provinceDefinitionArray.get(i).rgb[1] == pixels[p+1]) {
if ((byte)Victoria2Stats.provinceDefinitionArray.get(i).rgb[2] == pixels[p+2]) {
try {
if ((Victoria2Stats.provinceDataTable[i].ownerColor == null) && !(Victoria2Stats.provinceDataTable[i].lifeRating == 0)) {
pixels[p] = (byte)255;
pixels[p+1] = (byte)255;
pixels[p+2] = (byte)255;
} else {
pixels[p] = (byte)(Victoria2Stats.provinceDataTable[i].ownerColor.getRed());
pixels[p+1] = (byte)(Victoria2Stats.provinceDataTable[i].ownerColor.getBlue());
pixels[p+2] = (byte)(Victoria2Stats.provinceDataTable[i].ownerColor.getGreen());
}
} catch (NullPointerException e) {
// I realise this is a bad practice, but it is unrelated to the question and will be fixed later
}
}
}
}
}
}
}
BufferedImage buffer = new BufferedImage(mapProvinceImage.getWidth(), mapProvinceImage.getHeight(), mapProvinceImage.getType());
DataBuffer dataBuffer = new DataBufferByte(pixels, pixels.length);
SampleModel sampleModel = new ComponentSampleModel(DataBuffer.TYPE_BYTE, mapProvinceImage.getWidth(), mapProvinceImage.getHeight(), 3, mapProvinceImage.getWidth()*3, new int[]{0,1,2});
Raster raster = Raster.createRaster(sampleModel, dataBuffer, null);
buffer.setData(raster);
BufferedImage fixedImage = ImageUtils.verticalflip(buffer);
ImageIcon ii = new ImageIcon(fixedImage);
JScrollPane jsp = new JScrollPane(new JLabel(ii));
getContentPane().add(jsp);
setSize(800, 600);
setVisible(true);
}
}
Here is an example image: http://www.mediafire.com/?rttpk4o33b3oj74
I was thinking of somehow converting it to an indexed bitmap and then swapping the color indexes, but I couldn't figure out any way to successful assign it/recreate it with a color index with Java.
An instance of java.awt.image.LookupOp
with a suitable LookupTable
may be faster. An example is cited here.
ColorConvertOp
, illustrated here, would require a suitable ColorSpace
.
ImageJ
, mentioned here, can be used for batch processing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With