I was just wondering what the best way to read pixels from a BufferedImage. I want the pixels contained in a int[].
Here is my code right now:
try {
BufferedImage img = ImageIO.read(new File("C:\\Users\\Hardish\\Pictures\\test.png"));
BufferedImage intimg = Util.convertBufferedImage(img, BufferedImage.TYPE_INT_RGB);
int[] pixels = ((DataBufferInt)intimg.getRaster().getDataBuffer()).getData();
int co = Util.randomColor(255).getRGB();
if(co < 0)
co = -co;
StringBuilder sb = new StringBuilder();
for(int i = 0; i < pixels.length; i++){
Pixel px = new Pixel(Util.convertPixel(i, img.getWidth()), pixels[i]);
sb.append(px.toCompactString(true));
pixels[i] += co;
}
ImageIO.write(intimg, "jpg", new FileOutputStream("C:\\Users\\Hardish\\Pictures\\test.jpg"));
SaveHandler.saveCompressed(sb.toString(), "C:\\Users\\Hardish\\Pictures\\test.dat");
SaveHandler.saveString(sb.toString(), "C:\\Users\\Hardish\\Pictures\\test.sdat");
String pixDat = (String)(SaveHandler.readCompressed("C:\\Users\\Hardish\\Pictures\\test.dat"));
String[] pixs = pixDat.split(Pixel.PIXEL_SEPARATOR);
int[] pixelsRead = new int[pixs.length];
for(int i = 0; i < pixelsRead.length; i++){
pixelsRead[i] = Pixel.parseCompactPixel(pixs[i], true).val;
}
BufferedImage img2 = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
int[] pixelsW = ((DataBufferInt)img2.getRaster().getDataBuffer()).getData();
for(int i = 0; i < pixelsW.length; i++){
pixelsW[i] = pixelsRead[i];
}
ImageIO.write(img2, "jpg", new FileOutputStream("C:\\Users\\Hardish\\Pictures\\testRead.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
Here is the original:
Here is the change the pixels output:
Here is the read from file output:
Related
I need to display a PNG image in a SWT Java window, I'm using WindowBuilder and Eclipse.
First I tried with a label and this code:
Label lblNewLabel = new Label(this, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 1));
Image image = new Image(display, "img/selae_mini.png");
lblNewLabel.setImage(image)
It worked when executing in eclipse, but when I generate the jar, then, it doesn't work. Then I found on Stack Overflow that you must use ClassLoader.getSystemClassLoader().getResourceAsStream to get a bufferedImage and after that you must convert that bufferedImage to a ImageData, and finally convert that into a SWT Image.
So I tried with this code:
protected Image readImage(String path, Display display) {
InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream(path);
BufferedImage bi = null;
try {
bi = ImageIO.read(stream);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (stream != null)
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return new Image(display, convertToSWT(bi));
}
public static ImageData convertToSWT(BufferedImage bufferedImage) {
if (bufferedImage.getColorModel() instanceof DirectColorModel) {
DirectColorModel colorModel = (DirectColorModel) bufferedImage.getColorModel();
PaletteData palette = new PaletteData(
colorModel.getRedMask(),
colorModel.getGreenMask(),
colorModel.getBlueMask()
);
ImageData data = new ImageData(
bufferedImage.getWidth(),
bufferedImage.getHeight(), colorModel.getPixelSize(),
palette
);
WritableRaster raster = bufferedImage.getRaster();
int[] pixelArray = new int[3];
for (int y = 0; y < data.height; y++) {
for (int x = 0; x < data.width; x++) {
raster.getPixel(x, y, pixelArray);
int pixel = palette.getPixel(
new RGB(pixelArray[0], pixelArray[1], pixelArray[2])
);
data.setPixel(x, y, pixel);
}
}
return data;
} else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
IndexColorModel colorModel = (IndexColorModel) bufferedImage.getColorModel();
int size = colorModel.getMapSize();
byte[] reds = new byte[size];
byte[] greens = new byte[size];
byte[] blues = new byte[size];
colorModel.getReds(reds);
colorModel.getGreens(greens);
colorModel.getBlues(blues);
RGB[] rgbs = new RGB[size];
for (int i = 0; i < rgbs.length; i++) {
rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
}
PaletteData palette = new PaletteData(rgbs);
ImageData data = new ImageData(
bufferedImage.getWidth(),
bufferedImage.getHeight(),
colorModel.getPixelSize(),
palette
);
data.transparentPixel = colorModel.getTransparentPixel();
WritableRaster raster = bufferedImage.getRaster();
int[] pixelArray = new int[1];
for (int y = 0; y < data.height; y++) {
for (int x = 0; x < data.width; x++) {
raster.getPixel(x, y, pixelArray);
data.setPixel(x, y, pixelArray[0]);
}
}
return data;
}
return null;
}
The problem now is that my Image is a PNG file, and when doing the IF of the convertToSWT method, it gets that the image has a ColorModel called #pixelBits, so it returns null on that method! and I can't find any info about how to solve this problem.
I had this problem in before, and i resolved that. assuming your image has located in resource folder of your project:
String yourImg = "sampleImg.png";
...
Label swtImg = new Label(composite, SWT.NONE);
swtImg.setImage(new Image(display, YourClassName.calss.getResourceAsStream(yourImg)));
it's worked for me!
good luck ;)
I am trying to save a depth map from Kinect v2 which should come out as grayscale but every time that I try to save it as JPG file using the type BufferedImage.TYPE_USHORT_GRAY literally nothing happens (No warning on screen or in the console).
I manage to save it if I use types BufferedImage.TYPE_USHORT_555_RGB or BufferedImage.TYPE_USHORT_565_RGB but instead of being grayscale it come as out blueish or greenish depth maps.
Find below the code sample:
short[] depth = myKinect.getDepthFrame();
int DHeight=424;
int DWidth = 512;
int dx=0;
int dy = 21;
BufferedImage bufferDepth = new BufferedImage(DWidth, DHeight, BufferedImage.TYPE_USHORT_GRAY);
try {
ImageIO.write(bufferDepth, "jpg", outputFileD);
} catch (IOException e) {
e.printStackTrace();
}
Is there anything I am doing wrong to save it in grayscale?
Thanks in advance
You have to assign your data (depth) to the BufferedImage (bufferDepth) first.
A simple way to do this is:
short[] depth = myKinect.getDepthFrame();
int DHeight = 424;
int DWidth = 512;
int dx = 0;
int dy = 21;
BufferedImage bufferDepth = new BufferedImage(DWidth, DHeight, BufferedImage.TYPE_USHORT_GRAY);
for (int j = 0; j < DHeight; j++) {
for (int i = 0; i < DWidth; i++) {
int index = i + j * DWidth;
short value = depth[index];
Color color = new Color(value, value, value);
bufferDepth.setRGB(i, j, color.getRGB());
}
}
try {
ImageIO.write(bufferDepth, "jpg", outputFileD);
} catch (IOException e) {
e.printStackTrace();
}
"Base64Parts" is a string that has been split to equal parts, and I am trying to generate a QR code for each string and place it in a arraylist so that i can retrieve it and generate a GIF. Am I adding the bitmap images to the arraylist in the correct way? Because i can only retrieve "bmp_images.get(0)". Not others (eg-bmp_images.get(1)). My code is given below.
//Declaring QR code generator
QRCodeWriter writer = new QRCodeWriter();
//Declaring Array
ArrayList<Bitmap> bmp_images = new ArrayList<Bitmap>();
for (int i = 0; i < numberOfPartsSplit; i++){
try {
Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType, ErrorCorrectionLevel>();
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
BitMatrix bitMatrix = writer.encode(Base64Parts.get(i), BarcodeFormat.QR_CODE, 512, 512, hintMap);
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
bmp.setPixel(x, y, bitMatrix.get(x, y) ? Color.BLACK : Color.WHITE);
}
}
bmp_images.add(i,bmp); //the code added for arraylist of images
((ImageView) findViewById(R.id.image_holder)).setImageBitmap(bmp_images.get(0)); //use different values
} catch (WriterException e) {
e.printStackTrace();
}
((ImageView) findViewById(R.id.image_holder)).setImageBitmap(bmp_images.get(0));
paste this line outside for loop. Once all iteration done, set the needed index to get that particular value.
In the following code am trying to read a grayscale image, store the pixel values in a 2D array and rewrite the image with a different name.
The code is
package dct;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.io.File;
import javax.imageio.ImageIO;
public class writeGrayScale
{
public static void main(String[] args)
{
File file = new File("lightning.jpg");
BufferedImage img = null;
try
{
img = ImageIO.read(file);
}
catch(Exception e)
{
e.printStackTrace();
}
int width = img.getWidth();
int height = img.getHeight();
int[][] arr = new int[width][height];
Raster raster = img.getData();
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
arr[i][j] = raster.getSample(i, j, 0);
}
}
BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_BYTE_GRAY);
byte[] raster1 = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(arr,0,raster1,0,raster1.length);
//
BufferedImage image1 = image;
try
{
File ouptut = new File("grayscale.jpg");
ImageIO.write(image1, "jpg", ouptut);
}
catch(Exception e)
{
e.printStackTrace();
}
}// main
}// class
For this code , the error is
Exception in thread "main" java.lang.ArrayStoreException
at java.lang.System.arraycopy(Native Method)
at dct.writeGrayScale.main(writeGrayScale.java:49)
Java Result: 1
How to remove this error to write the grayscale image?
I found this: "ArrayStoreException -- if an element in the src array could not be stored into the dest array because of a type mismatch." http://www.tutorialspoint.com/java/lang/system_arraycopy.htm
Two thoughts:
You're copying an int-array into a byte-array.
That's not part of the exceptions, but are the dimensions right? arr is a two-dimensional array, raster1 is a one-dimensional array.
And you can't just change the byte-array in a two-dimensional one ignoring the output of the method you're calling.
Change int[][] arr to byte[] arr like this.
byte[] arr = new byte[width * height * 4];
for (int i = 0, z = 0; i < width; i++) {
for (int j = 0; j < height; j++, z += 4) {
int v = getSample(i, j, 0);
for (int k = 3; k >= 0; --k) {
arr[z + k] = (byte)(v & 0xff);
v >>= 8;
}
}
}
I am getting the int array from png image how I will convert this to bufferdimage or creating new PNG file ?
int[] pixel = new int[w1*h1];
int i = 0;
for (int xx = 0; xx < h1; xx++) {
for (int yy = 0; yy < w1; yy++) {
pixel[i] = img.getRGB(yy, xx);
i++;
}
}
If you have an array of integers which are packed RGB values, this is the java code to save it to a file:
int width = 100;
int height = 100;
int[] rgbs = buildRaster(width, height);
DataBuffer rgbData = new DataBufferInt(rgbs, rgbs.length);
WritableRaster raster = Raster.createPackedRaster(rgbData, width, height, width,
new int[]{0xff0000, 0xff00, 0xff},
null);
ColorModel colorModel = new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
BufferedImage img = new BufferedImage(colorModel, raster, false, null);
String fname = "/tmp/whatI.png";
ImageIO.write(img, "png", new File(fname));
System.out.println("wrote to "+fname);
The reason for the arrays 0xff0000, 0xff00, 0xff is that the RGB bytes are packed with blue in the least significant byte. If you pack your ints different, alter that array.
You can rebuild the image manually, this is however a pretty expensive operation.
BufferedImage image = new BufferedImage(64, 64, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
for(int i = 0; i < pixels.size(); i++)
{
g.setColor(new java.awt.Color(pixels.get(i).getRed(), pixels.get(i).getGreen(), pixels.get(i).getBlue()));
g.fillRect(pixels.get(i).getxPos(), pixels.get(i).getyPos(), 1, 1);
}
try
{
ImageIO.write(image, "PNG", new File("imageName.png"))
}
catch(IOException error)
{
error.printStackTrace();
}
I formatted your image array into an object, this is personal preference tho (of course you could us an int array with this model as well). Keep in mind that you can always add the alpha to there as well.
Try the ImageIO class, which can take a byte array representing pixel data to build an image object and then writing it out in a particular format.
try {
BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(yourBytes));
ImageIO.write(bufferedImage, "png", new File("out.png"));
} catch (IOException e) {
e.printStackTrace();
}