I'm trying to convert a buffered image to a Matrix, but it throws an UnsupportedOperationException, which I have never seen before
public static Mat readMatImage(String path) {
Mat mat = null;
BufferedImage image;
try {
image = ImageIO.read(new FileInputStream(path));
mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3);
byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.out.println(data[data.length - 1]);
mat.put(0, 0, data);
} catch (IOException e) {
e.printStackTrace();
}
return mat;
}
Exception in thread "main" java.lang.UnsupportedOperationException: Provided data element number (4000000) should be multiple of the Mat channels count (3)
I think you should consider your read-image type because your image must be single channel and 8-bit to cast it to a mat element. If your image is RGB, try to convert it to binary image.
Related
I am trying to threshold my images, but some of them have problem with casting to DataBufferByte. I post here two types of pictures - the first (the test1.jpg is good and can be casted to DataBufferByte), the second (test2.jpg throwing an exception).
Images:
Here is my code:
public static void main(String[] args) throws IOException {
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
BufferedImage bufferedImage = ImageIO.read(new File("/test/test2.jpg"));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream);
byte[] input = byteArrayOutputStream.toByteArray();
InputStream is = new ByteArrayInputStream(input);
bufferedImage = ImageIO.read(is);
byte[] data = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
Mat mat = new Mat(bufferedImage.getHeight(), bufferedImage.getWidth(), CvType.CV_8UC3);
mat.put(0, 0, data);
Mat mat1 = new Mat(bufferedImage.getHeight(),bufferedImage.getWidth(),CvType.CV_8UC1);
Imgproc.cvtColor(mat, mat1, Imgproc.COLOR_RGB2GRAY);
byte[] data1 = new byte[mat1.rows() * mat1.cols() * (int)(mat1.elemSize())];
mat1.get(0, 0, data1);
Mat dst = new Mat();
Imgproc.adaptiveThreshold(mat1, dst, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 11, 15);
MatOfByte matOfByte = new MatOfByte();
Imgcodecs.imencode(".jpg", dst, matOfByte);
ByteArrayInputStream inputStream = new ByteArrayInputStream(matOfByte.toArray());
bufferedImage = ImageIO.read(inputStream);
ImageIO.write(bufferedImage, "jpg", new File("/test_output/test2.jpg"));
}
The output for test1.jpg image is correct:
But the second image throwing an exception
Exception in thread "main" java.lang.ClassCastException:
java.awt.image.DataBufferInt cannot be cast to
java.awt.image.DataBufferByte
at line
byte[] data = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
What is the problem ? Why the one .jpg image is converted without problems but second throwing an exception?
Both are not of the same format. One using 8-bit for color representation and the other 3x8-bit (so 4 bytes, with padding or transparency)?
Looking at it give:
image1 : JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 449x361, components 3
image2 : PNG image data, 617 x 353, 8-bit/color RGBA, non-interlaced
You may use the getDataType() method on the buffer to get the size of the color representation.
What I'm trying to do is create a BufferedImage from a byte array. Here is what I'm doing now:
try {
ByteArrayInputStream in = new ByteArrayInputStream(bytearray);
BufferedImage bImageFromConvert = ImageIO.read(in);
Color color = new Color(bImageFromConvert.getRGB((int) local_car.x, (int) local_car.z));
System.out.println("R :: "+color.getRed() + " B :: "+color.getBlue() + " G :: "+color.getGreen());
} catch (IOException e) {
e.printStackTrace();
}
}
The documentation of ImageIO.read says:
Returns a BufferedImage as the result of decoding a supplied URL with an ImageReader chosen automatically from among those currently registered. An InputStream is obtained from the URL, which is wrapped in an ImageInputStream. If no registered ImageReader claims to be able to read the resulting stream, null is returned.
I'm receiving a null pointer exception from ImageIO.read() returning null. I am sending my bytearray in the form of RGBA. Why is ImageIO.read returning null?
The ImageIO functions are for reading files and expect the input stream to be in one of the file formats such as PNG or JPG, not for reading simple arrays of rgba. To read in a simple array try something like:
int width = 256;
int height = 256;
final int bytes_per_pixel = 4;
byte[] raw = new byte[width * height * bytes_per_pixel];
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
IntBuffer intBuf
= ByteBuffer.wrap(raw)
.order(ByteOrder.LITTLE_ENDIAN)
.asIntBuffer();
int[] array = new int[intBuf.remaining()];
intBuf.get(array);
image.setRGB(0, 0, width, height, array, 0, width);
I'm designing a program that stores geography data on the JavaFX platform, and whenever I convert an image from a JavaFX Image into a BufferedImage then a ByteArray (for the purpose of serialization) before converting to a Buffered Image and then JavaFX Image again, it gets slightly corrupt. Here's the code I'm using to convert back and forth:
private byte [] loadImageData (Image image){
try{
//creating a byte array output stream from the Image
BufferedImage bi = SwingFXUtils.fromFXImage(image, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream(1000);
ImageIO.write(bi, "png", baos );
baos.flush();
byte[] imageData = baos.toByteArray();
baos.close();
return imageData;
}catch (Exception e){
e.printStackTrace();
}
}
public Image restoreMapData (byte[] data){
try{
//converting back to an image
InputStream in = new ByteArrayInputStream(data);
BufferedImage bi = ImageIO.read(in);
return SwingFXUtils.toFXImage(bi, null);
}catch(Exception e){
e.printStackTrace();
return null;
}
}
Could there be an error elsewhere? I've attached a corrupted and un-corrupt picture of the data.
I also noticed that if I convert to BufferedImage with a type TYPE_INT_ARGB it greatly diminishes the effect.
i have a 1 D array pixel which contains pixel values of a 512x512 grayscale image. i want to write it into a png file. i wrote the following code , but it just creates a blank image.
public void write(int width ,int height, int[] pixel) {
try {
// retrieve image
BufferedImage writeImage = new BufferedImage(512,512,BufferedImage.TYPE_BYTE_GRAY);
File outputfile = new File("saved.png");
WritableRaster raster = (WritableRaster) writeImage.getData();
raster.setPixels(0,0,width,height,pixel);
ImageIO.write(writeImage, "png", outputfile);
} catch (IOException e) {
}
The Raster returned is a copy of the image data is not updated if the image is changed.
Try setting the new Raster object back to the image.
WritableRaster raster = (WritableRaster)writeImage.getData();
raster.setPixels(0, 0, width, height, pixel);
writeImage.setData(raster);
I am trying to convert a PNG image to a JPEG image following this tutorial. But I encounter a problem. The resulting image has a pink layer.
Does anyone have a solution for this problem? Or what code should I use in order to convert the image into the desired format?
Thanks in advance!
Create a BufferedImage of desired size, e.g.:
BufferedImage img = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB)
fill it with a proper background color:
img.getGraphics().fillRect(....)
Call drawImage on the image's graphics atop of that background:
img.getGraphics().drawImage(image, 0, 0, null);
then write down your image as JPG as usual.
Which color mode are you using? While you create buffered image object, try adding the type like this option.
File newFile = new File(path + fileName + "." + Strings.FILE_TYPE);
Image image = null;
try {
image = ImageIO.read(url); // I was using an image from web
} catch (IOException e1) {
e1.printStackTrace();
}
image = image.getScaledInstance(width, height, Image.SCALE_SMOOTH);
try {
BufferedImage img = toBufferedImage(image);
ImageIO.write(img, "jpg", newFile);
} catch (IOException e) {
e.printStackTrace();
}
}
private static BufferedImage toBufferedImage(Image src) {
int w = src.getWidth(null);
int h = src.getHeight(null);
int type = BufferedImage.TYPE_INT_RGB; // other options
BufferedImage dest = new BufferedImage(w, h, type);
Graphics2D g2 = dest.createGraphics();
g2.drawImage(src, 0, 0, null);
g2.dispose();
return dest;
}