Converting BufferedImage to binary without image going completely black - java

i am trying to create an OCR to read 7 segment led off of old camera reals. this is my pre processing (ignore the random imports been trying a bunch of options)right now i am changing the image to negative from orange and gray and changing it to Grayscale, once i try to change gray scale to binary it just blacks out the image and i have no clue to remedy it with this code.
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.color.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class PreProcess2 {
public static void main(String [] args) {
BufferedImage img = null;
File dir = new File ("Directory/file/example photo");
File[] dirList = dir.listFiles();
for (int i = 1; i < dirList.length; i++) {
try{
img = ImageIO.read(dirList[i].getAbsoluteFile());
int d = 2;
int iw = img.getWidth();
int ih = img.getHeight();
int xb = ((((iw/d)/d)+(iw/d)));
int yb = ((((ih/d)/d)+(ih/d)));
try {
//Isolates Width
for (int x = xb ; x <= (iw-1); x++){
//Isolates Height
for (int y = yb; y <= (ih-1); y++){
int p = img.getRGB(x, y);
int a = (p>>24)&0xff;
int r = (p>>16)&0xff;
int g = (p>>8)&0xff;
int b = p&0xff;
//subtract RGB from 255
r = 255 - r;
g = 255 - g;
b = 255 - b;
//set new RGB from 255
p = (a<<24) | (r<<16) | (g<<8) | b;
img.setRGB(x, y, p);
}
}
//Prints out if pixel is out of bounds
}catch (ArrayIndexOutOfBoundsException e) {
System.out.println("out of bounds");
}
BufferedImage result = new BufferedImage(
img.getWidth(),
img.getHeight(),
BufferedImage.TYPE_BYTE_GRAY);
Graphics g = result.getGraphics();
g.drawImage(img, 0, 0, null);
g.dispose();
BufferedImage gray = new BufferedImage(result.getWidth(), result.getHeight(),
BufferedImage.TYPE_BYTE_BINARY);
BufferedImage croppedImage = gray.getSubimage(615, 445, 110, 35);
//Saves file to processed file location
File outputfile = new File(dir +"/Processed/" + dirList[i].getName());
ImageIO.write(croppedImage, "jpg", outputfile);
//Print out if not able to retrieve file
} catch (IOException e) {
System.out.println("Done");
}
}
}
}
Blacked out
Negative
UPDATE:
BufferedImage binary = new BufferedImage(iw, ih, BufferedImage.TYPE_BYTE_BINARY);
Graphics biG = binary.getGraphics();
biG.drawImage(gray, 0, 0, null);
biG.dispose();
managed to find a partial answer with the help of a colleague now i need to figure out how to clean up the noise in the images, any ideas?

Related

A program that cuts GIFs into frames and converts them into pixels is using too much memory

I wrote a code which splits a gif-image into frames.
Then, they are scaled-down into smaller ones, the resolution is 128 * 128 pixels. Then they combine a full frame with a specific resolution.
The getFrames (String path) method gets the GIF file along the path from the jar and creates image frames.
The getResizedimages (…) method cuts the frame into smaller 128 by 128 images.
The getPixels (Bufferedlmage image) method gets an array of pixels from an image.
The problem is that during the execution of this code (via the test method), a very very large amount of memory is used even at the stage of execution of the getFrames (…) method or the getFramesRaw (…) method.
import com.sun.imageio.plugins.gif.GIFImageReader;
import com.sun.imageio.plugins.gif.GIFImageReaderSpi;
import org.apache.commons.io.FileUtils;
import org.bukkit.map.MapPalette;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class Gif {
static void test(String path, int height, int width) {
List<BufferedImage> images = getFrames(path);
for (int x = 0; x < width; x ++) for (int y = 0; y < height; y ++)
getResizedFrames(images, width, height, x, y).forEach(image -> getPixels(image));
}
#SuppressWarnings("deprecation")
public static byte[] getPixels(BufferedImage image) {
int pixelCount = image.getWidth() * image.getHeight();
int[] pixels = new int[pixelCount];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
byte[] colors = new byte[pixelCount];
for (int i = 0; i < pixelCount; i++)
colors[i] = MapPalette.matchColor(new Color(pixels[i], true));
return colors;
}
public static BufferedImage getScaledImage(BufferedImage image) {
BufferedImage newImg = new BufferedImage(128, 128, 3);
Graphics2D g2 = newImg.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(image, 0, 0, 128, 128, null);
g2.dispose();
return newImg;
}
public static BufferedImage cropImage(BufferedImage completeImg, int width, int height, int xCoord, int yCoord) {
int coordWidth = completeImg.getWidth() / width;
int coordHeight = completeImg.getHeight() / height;
BufferedImage croppedImg = new BufferedImage(completeImg.getWidth(), completeImg.getHeight(), 1);
Graphics2D g2 = (Graphics2D)croppedImg.getGraphics();
g2.drawImage(completeImg, 0, 0, completeImg.getWidth(), completeImg.getHeight(), null);
g2.dispose();
BufferedImage image = croppedImg.getSubimage(coordWidth * xCoord, coordHeight * yCoord, coordWidth, coordHeight);
return getScaledImage(image);
}
public static java.util.List<BufferedImage> getFramesRaw(String path) {
java.util.List<BufferedImage> frames = new ArrayList<>();
try {
File file = File.createTempFile("data", ".gif");
InputStream stream = Main.class.getResourceAsStream(path);
FileUtils.copyInputStreamToFile(stream, file);
stream.close();
ImageInputStream inputStream = ImageIO.createImageInputStream(file);
ImageReader ir = new GIFImageReader(new GIFImageReaderSpi());
ir.setInput(inputStream);
int number = ir.getNumImages(true);
for (int i = 0; i < number; i++) frames.add(ir.read(i));
inputStream.close();
System.gc();
} catch (Exception e) {
e.printStackTrace();
}
return frames;
}
public static java.util.List<BufferedImage> getFrames(String path) {
java.util.List<BufferedImage> copies = new ArrayList<>();
java.util.List<BufferedImage> frames = getFramesRaw(path);
copies.add(frames.remove(0));
int width = copies.get(0).getWidth(), height = copies.get(0).getHeight();
for (BufferedImage frame : frames) {
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = img.getGraphics();
g.drawImage(copies.get(copies.size()-1),0,0,null);
g.drawImage(frame,0,0,null);
copies.add(img);
}
return copies;
}
public static java.util.List<BufferedImage> getResizedFrames(java.util.List<BufferedImage> frames, int width, int height, int x, int y) {
List<BufferedImage> copies = new ArrayList<>();
for (BufferedImage image : frames)
copies.add(cropImage(image, width, height, width - 1 - x, height - 1 - y));
return copies;
}
}
I need your help.
The reason your program uses a lot of memory, is because your code operates at all the frames at each step (in many small loops). All the decoded image data for all the frames will be held in memory at the same time, resulting in unnecessary memory usage. While this may feel logical, it is for sure not efficient.
Instead, create one loop that does all the needed operations for a single frame, before moving on to the next.
Something like this:
public static void test(String path) throws IOException {
List<BufferedImage> thumbnails = new ArrayList<>();
readFrames(path, image -> thumbnails.add(getScaledImage(image)));
}
private static void readFrames(String path, Consumer<BufferedImage> forEachFrame) throws IOException {
try (ImageInputStream inputStream = ImageIO.createImageInputStream(GifSplitter.class.getResourceAsStream(path))) {
Iterator<ImageReader> readers = ImageIO.getImageReaders(inputStream); // ImageIO detects format, no need to hardcode GIF plugin
if (!readers.hasNext()) {
return;
}
ImageReader ir = readers.next();
ir.setInput(inputStream);
// For GIF format (which does not contain frame count in header),
// it's more efficient to just read each frame until IOOBE occurs,
// instead of invoking getNumImages(true)
int i = 0;
while (i >= 0) {
try {
BufferedImage image = ir.read(i++);
// crop, scale, etc, for a SINGLE image
forEachFrame.accept(image);
}
catch (IndexOutOfBoundsException endOfGif) {
// No more frames
break;
}
}
ir.dispose();
}
}

Java: My height map generator only writes binary

So today I started with a new project. I want to make a simple heightmap generator in java, so I tried the following:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Heightmap {
public static int width = 200;
public static int height = 200;
public static void main(String[] args) {
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY );
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
bufferedImage.setRGB(x, y, (byte )(Math.random() * 256 + 128) ); // + 128 because byte goes from -128 to 127
}
}
File outputFile = new File("heightmap.png");
try {
ImageIO.write(bufferedImage, "png", outputFile);
}catch (IOException ioex){
ioex.printStackTrace();
}
}
}
The code is very simple, I plan to try perlin noise as the next step. But first I need to resolve this problem:
Generated Heightmap
The pixels in heightmap.png are either completely white, or completely black. There's no grays in the image, which of course is necessary in a heightmap. Does anyone know what I did wrong?
is it the BufferedImage.TYPE_BYTE_GRAY part? If so, what should I use instead?
After a friend set me on the right track, I found the solution.
Instead of BufferedImage.TYPE_BYTE_GRAY I used BufferdImage.TYPE_INT_RGB. So this is indeed where I went wrong. Also I added the object Color randomColor, wherein the RGB values all share the same integer with a value from 0 to 255. Then in BufferedImage.setRGB I use the color code of randomColor (so R,G,B = 255 gives #FFFFFF, which is white) as the value of pixel (x,y):
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Heightmap {
public static int width = 200;
public static int height = 200;
public static void main(String[] args) {
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB );
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
int randomValue = (int)(Math.random() * 256);
Color randomColor = new Color( randomValue, randomValue, randomValue);
bufferedImage.setRGB(x, y, randomColor.getRGB());
}
}
File outputFile = new File("heightmap.png");
try {
ImageIO.write(bufferedImage, "png", outputFile);
}catch (IOException ioex){
ioex.printStackTrace();
}
}
}
Now the heightmap.png gives what I expected: Heightmap.png

How to find different shades of a color in Java?

If I have the RBG code of a number, such as -16777216 (black), how can I find other similar shades of black using this color code?
I'm trying to convert an image to monochrome by marking all pixels which are not -16777216 to be white. However, often there are varying shades of black which are found, but they are lost because they are not an exact match.
Edit: I'm having a bit of trouble. When I try to use this color to find shades of black, so I can ignore them while converting the other pixels to white, this is my result:
Source:
Result:
Code:
package test;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;
import javax.imageio.ImageIO;
public class Test
{
public static void main(String[] args)
{
try
{
BufferedImage source = ImageIO.read( new URL("http://i.imgur.com/UgdqfUY.png"));
//-16777216 = black:
BufferedImage dest = makeMonoChromeFast(source, -16777216);
File result = new File("D:/result.png");
ImageIO.write(dest, "png", result);
}
catch (Exception e)
{
e.printStackTrace();;
}
}
public static BufferedImage makeMonoChromeFast(BufferedImage source, int foreground)
{
int background = -1; //white;
Color fg = new Color(foreground);
int color = 0;
for (int y = 0; y < source.getHeight(); y++)
{
for (int x = 0; x < source.getWidth(); x++)
{
color = source.getRGB(x, y);
if ( color == foreground )
continue;
if (! isIncluded(fg, color, 50))
source.setRGB(x, y, background);;
}
}
return source;
}
public static boolean isIncluded(Color target, int pixelColor, int tolerance)
{
Color pixel = new Color(pixelColor);
int rT = target.getRed();
int gT = target.getGreen();
int bT = target.getBlue();
int rP = pixel.getRed();
int gP = pixel.getGreen();
int bP = pixel.getBlue();
return(
(rP-tolerance<=rT) && (rT<=rP+tolerance) &&
(gP-tolerance<=gT) && (gT<=gP+tolerance) &&
(bP-tolerance<=bT) && (bT<=bP+tolerance) );
}
}
You might use this 'look for color with difference tolerance' method.
public static boolean isIncluded(Color target, Color pixel, int tolerance) {
int rT = target.getRed();
int gT = target.getGreen();
int bT = target.getBlue();
int rP = pixel.getRed();
int gP = pixel.getGreen();
int bP = pixel.getBlue();
return(
(rP-tolerance<=rT) && (rT<=rP+tolerance) &&
(gP-tolerance<=gT) && (gT<=gP+tolerance) &&
(bP-tolerance<=bT) && (bT<=bP+tolerance) );
}
Here it is used to get the outline (motorcycle-03.jpg) of the motorcycle (motorcycle.jpg), while stripping out the 'faint gray overlay'.
motorcycle.jpg
motorcycle-03.png
ImageOutline.java
This code requires some patience (when running). See Smoothing a jagged path for code that does the same thing much faster.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.geom.Area;
import javax.imageio.ImageIO;
import java.io.File;
import java.util.Date;
import javax.swing.*;
/* Motorcycle image courtesy of ShutterStock
http://www.shutterstock.com/pic-13585165/stock-vector-travel-motorcycle-silhouette.html */
class ImageOutline {
public static Area getOutline(BufferedImage image, Color color, boolean include, int tolerance) {
Area area = new Area();
for (int x=0; x<image.getWidth(); x++) {
for (int y=0; y<image.getHeight(); y++) {
Color pixel = new Color(image.getRGB(x,y));
if (include) {
if (isIncluded(color, pixel, tolerance)) {
Rectangle r = new Rectangle(x,y,1,1);
area.add(new Area(r));
}
} else {
if (!isIncluded(color, pixel, tolerance)) {
Rectangle r = new Rectangle(x,y,1,1);
area.add(new Area(r));
}
}
}
}
return area;
}
public static boolean isIncluded(Color target, Color pixel, int tolerance) {
int rT = target.getRed();
int gT = target.getGreen();
int bT = target.getBlue();
int rP = pixel.getRed();
int gP = pixel.getGreen();
int bP = pixel.getBlue();
return(
(rP-tolerance<=rT) && (rT<=rP+tolerance) &&
(gP-tolerance<=gT) && (gT<=gP+tolerance) &&
(bP-tolerance<=bT) && (bT<=bP+tolerance) );
}
public static BufferedImage drawOutline(int w, int h, Area area) {
final BufferedImage result = new BufferedImage(
w,
h,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = result.createGraphics();
g.setColor(Color.white);
g.fillRect(0,0,w,h);
g.setClip(area);
g.setColor(Color.red);
g.fillRect(0,0,w,h);
g.setClip(null);
g.setStroke(new BasicStroke(1));
g.setColor(Color.blue);
g.draw(area);
return result;
}
public static BufferedImage createAndWrite(
BufferedImage image,
Color color,
boolean include,
int tolerance,
String name)
throws Exception {
int w = image.getWidth();
int h = image.getHeight();
System.out.println("Get Area: " + new Date() + " - " + name);
Area area = getOutline(image, color, include, tolerance);
System.out.println("Got Area: " + new Date() + " - " + name);
final BufferedImage result = drawOutline(w,h,area);
displayAndWriteImage(result, name);
return result;
}
public static void displayAndWriteImage(BufferedImage image, String fileName) throws Exception {
ImageIO.write(image, "png", new File(fileName));
JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(image)));
}
public static void main(String[] args) throws Exception {
final BufferedImage outline = ImageIO.read(new File("motorcycle.jpg"));
BufferedImage crop = outline.getSubimage(17,35,420,270);
displayAndWriteImage(crop, "motorcycle-01.png");
BufferedImage crude = createAndWrite(crop, Color.white, false, 60, "motorcycle-02.png");
BufferedImage combo = createAndWrite(crude, Color.red, true, 0, "motorcycle-03.png");
}
}
With the code seen in the question, with a tolerance of 150, I see this.
In general, I think that the way to go is use the sRGB to Grey-scale conversion formulae described on this Wikipedia page, and then choose a particular "grey" value as being the boundary between black and white. (The choice is up to you ...)
But say that you already have RGB values that represent grey-scale points, you should find that they all have equal red, green and blue values. If that is actually the case, then you simply need to pick one of the colour components of an RGB and compare it against the same colour value of your chosen "grey".
If you need to discriminate multiple shades of black, grey and white, then choose multiple boundary "colours".
Edit: I'm having a bit of trouble. When I try to use this color to find shades of black, so I can ignore them while converting the other pixels to white, this is my result:
What you are seeing there is the effects of anti-aliasing. There is actually very little "pure" black in the image. A lot of what looks black to the human eye is actually dark, or not so dark grey. You need to make your boundary colour (i.e. boundary between "black" and "not black") more grey.

setRGB() doesn't seem to change the color

could you please tell me why the pixels won't set to red
Color myColor = new Color(255, 0, 0);
int rgb = myColor.getRGB();
String fileName = Config.IMAGEFILEPATH + "first_nodal_domain "
+ "full.png";
BufferedImage bi = new BufferedImage(AZIMUTH_RES, ELEVATION_RES, BufferedImage.TYPE_USHORT_GRAY);
for (int i = 0; i < AZIMUTH_RES; i++){
for (int j = 0; j < ELEVATION_RES; j++){
bi.setRGB(i,j,(255 << 16) + (255 << 8) + 255);
}
}
for (Point draw: shadedPoints){
bi.setRGB(draw.x, draw.y, rgb);
}
BufferedImage scaledImage = new BufferedImage(
1000, 1000, BufferedImage.TYPE_USHORT_GRAY);
// Paint scaled version of image to new image
Graphics2D graphics2D = scaledImage.createGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2D.drawImage(bi, 0, 0, 1000, 1000, null);
try {
// write out image to file as .png
ImageIO.write(scaledImage, "png", new File(fileName));
} catch (IOException ex) {
Logger.getLogger(NodalDomainsDrawing.class.getName()).log(Level.SEVERE, null, ex);
}
bi.flush();
thanks in advance.
With respect, you seem to be going about this very strangely...
Rather then trying to draw directly to the pixel level, you should be making use of the Graphics API capabilities.
For example, clearing the image is going to be significantly faster using Graphics#fillRect then looping through and setting each pixel.
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
public class TestImage02 {
public static void main(String[] args) {
Color myColor = new Color(255, 0, 0);
// int rgb = myColor.getRGB();
List<Point> shadedPoints = new ArrayList<>(25);
for (int index = 0; index < 100; index++) {
shadedPoints.add(new Point(index, index));
}
BufferedImage bi = new BufferedImage(100, 100, BufferedImage.TYPE_USHORT_GRAY);
Graphics2D g2d = bi.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, 100, 100);
// for (int i = 0; i < 100; i++) {
// for (int j = 0; j < 100; j++) {
// bi.setRGB(i, j, (255 << 16) + (255 << 8) + 255);
// }
// }
g2d.setColor(myColor);
for (Point draw : shadedPoints) {
// bi.setRGB(draw.x, draw.y, rgb);
g2d.drawLine(draw.x, draw.y, 1, 1);
}
g2d.dispose();
BufferedImage scaledImage = new BufferedImage(
1000, 1000, BufferedImage.TYPE_USHORT_GRAY);
// Paint scaled version of image to new image
Graphics2D graphics2D = scaledImage.createGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2D.drawImage(bi, 0, 0, 1000, 1000, null);
graphics2D.dispose();
try {
// write out image to file as .png
ImageIO.write(scaledImage, "png", new File("Test.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
bi.flush();
}
}
I ran your original code (with modifications to make it work) and it worked fine, but I've post some additional code that use Graphics instead.
You should make sure that you are calling Graphics#dispose. On different OS'es the Graphics object can behave differently, meaning that some times, until you dispose of the graphics object, it may not actually paint anything...

java.ImageIO.write completely corrupted PNG and/or BMP with incorrect data

Any help most appreciated, this is driving me insane. I'm doing exactly what I can find from google etc. and it's not working.
I'm having a lot of difficulty creating and writing BMP or PNG images in java. Either would do, I was going to go with BMP but I get an image which is correct in the lower section for what I want but the upper section is just a black block a lot of the time (not always).
With any other file format, including PNG, the resulting file is completely corrupted. Java says PNG, BMP and others are supported on my system according to the filetypessupported method.
If you're wondering what it's for, I'm trying to draw a representation of an area based on a robot's sensors.
And if you're wondering why I'm not using Graphics2d to draw a rectangle rather than doing it pixel by pixel, Graphics2d appears to be drawing rectangles that are bigger than what I ask for.
Here is my code for if I were to write a PNG (with a lot snipped out) and the bmp writing
commented out:
private BufferedImage bufImage = null;
private ImageIO imageIO = null;
private int blobSize = 5;
private String pngPath = f.getAbsolutePath() + "test.png";
private java.io.File f = new java.io.File("");
private String bmpPath = f.getAbsolutePath() + "test.bmp";
Map(int sizeX, int sizeY){
bufImage = new BufferedImage(sizeX, sizeY, BufferedImage.TYPE_INT_RGB);
//set all pixels of bufImage to white
for (int x = 0; x < sizeX; x++){
for (int y = 0; y < sizeY; y++){
bufImage.setRGB(x, y, Color.WHITE.getRGB());
}
}
saveBMP();
}
public void addObstacle(int x, int y, int fiducial){
//invert y (y == 0 is upper left on bitmap)
y = 1674 - y;
//10*10 pixels
for (int w = x; w < x + blobSize && w < sizeX && w >= 0 ; w++){
for (int h = y; h < y + blobSize && h < sizeY && h >= 0; h++){
try{
bufImage.setRGB(w, h, Color.BLACK.getRGB());
//System.out.println(h);
}
catch (ArrayIndexOutOfBoundsException e){
System.out.println("x: " + w + " y: " + h);
}
//System.out.println(h);
}
}
//bufImage.setRGB(x, y, Color.BLACK.getRGB());
saveBMP();
}
public void saveBMP(){
try {
RenderedImage rendImage = bufImage;
//ImageIO.write(rendImage, "bmp", new File(bmpPath));
ImageIO.write(rendImage, "PNG", new File(pngPath));
//ImageIO.write(rendImage, "jpeg", new File(jpegPath));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Maybe you could start with something that works and work from there?
Note that for better performances you should create a "compatible" BufferedImage:
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(width,height,Transparency.TRANSLUCENT)
whose "ARGB" shall depend on your OS.
Here's a code that creates a 320x160 all white .png file based on your code.
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
public class SO {
public static void main( final String[] args ) {
final BufferedImage img = map( 320, 160 );
savePNG( img, "/tmp/test.png" );
}
private static BufferedImage map( int sizeX, int sizeY ){
final BufferedImage res = new BufferedImage( sizeX, sizeY, BufferedImage.TYPE_INT_RGB );
//set all pixels of bufImage to white
for (int x = 0; x < sizeX; x++){
for (int y = 0; y < sizeY; y++){
res.setRGB(x, y, Color.WHITE.getRGB() );
}
}
return res;
}
private static void savePNG( final BufferedImage bi, final String path ){
try {
RenderedImage rendImage = bi;
//ImageIO.write(rendImage, "bmp", new File(bmpPath));
ImageIO.write(rendImage, "PNG", new File(path));
//ImageIO.write(rendImage, "jpeg", new File(jpegPath));
} catch ( IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Note that setRGB(...) always work in ARGB so:
res.setRGB(x, y, Color.WHITE.getRGB() );
and:
res.setRGB(x, y, 0xFFFFFFFF );
are equivalent.
There are more efficient way to fill a solid background but knowing how to manipulate pixel ARGB components directly may come in handy once speed is needed.
I don't see a problem with your approach, although I'm guessing at your calling code. Note that instead of setting pixels directly, you can draw into a buffered image. Here's a call to get(100, 100):
private BufferedImage get(int sizeX, int sizeY) {
BufferedImage bufImage = new BufferedImage(
sizeX, sizeY, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < sizeX; x++) {
for (int y = 0; y < sizeY; y++) {
bufImage.setRGB(x, y, Color.RED.getRGB());
}
}
Graphics2D g2d = bufImage.createGraphics();
g2d.setColor(Color.green);
g2d.fillRect(0, 0, sizeX / 2, sizeY / 2);
g2d.fillRect(sizeX / 2, sizeY / 2, sizeX, sizeY);
g2d.dispose();
try {
ImageIO.write(bufImage, "PNG", new File("test.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
return bufImage;
}
Addendum: ImageIO.write(bufImage, "BMP", new File("test.bmp")); works too.

Categories

Resources