Byte Array to Image object - java

I am given a byte[] array in Java which contains the bytes for an image, and I need to output it into an image. How would I go about doing this?
Much thanks

BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));

If you know the type of image and only want to generate a file, there's no need to get a BufferedImage instance. Just write the bytes to a file with the correct extension.
try (OutputStream out = new BufferedOutputStream(new FileOutputStream(path))) {
out.write(bytes);
}

From Database.
Blob blob = resultSet.getBlob("pictureBlob");
byte [] data = blob.getBytes( 1, ( int ) blob.length() );
BufferedImage img = null;
try {
img = ImageIO.read(new ByteArrayInputStream(data));
} catch (IOException e) {
e.printStackTrace();
}
drawPicture(img); // void drawPicture(Image img);

Since it sounds like you already know what format the byte[] array is in (e.g. RGB, ARGB, BGR etc.) you might be able to use BufferedImage.setRGB(...), or a combination of BufferedImage.getRaster() and WritableRaster.setPixels(...) or WritableRaster.setSamples(...). Unforunately both of these methods require you transform your byte[] into one of int[], float[] or double[] depending on the image format.

According to the Java docs, it looks like you need to use the MemoryImageSource Class to put your byte array into an object in memory, and then use Component.createImage(ImageProducer) next (passing in your MemoryImageSource, which implements ImageProducer).

Related

How to get byte array form javafx.scene.image.Image object?

I want to save image into database. I have a Customer model that has Image property in it. I am creating a class that handle all the customer related database operations. In that class I have a method that takes in Customer object and inserts it into the database. Therefore, I have only Customer object to work with. How can I convert that Image object into byte array so that I can insert it into the datbase?
I know how to extract byte array from a file object. Should I change the customer model to contain image file instead of image object?
This worked for me:
Image image = customer.getImage();
BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image, null);
ByteArrayOutputStream byteArrayInputStream = new ByteArrayOutputStream();
try {
ImageIO.write(bufferedImage, "jpeg", byteArrayInputStream);
} catch (IOException e) {
e.printStackTrace();
}
byte[] buffer = byteArrayInputStream.toByteArray();

How to get byte[] from javafx imageView?

How do i get byte[] from javafx image/imageview class? I want to store my image as a Blob into my database.This is the method that i use for it
public PreparedStatement prepareQuery(HSQLDBConnector connector) {
try {
Blob logoBlob = connector.connection.createBlob();
logoBlob.setBytes(0,logo.getImage());//stuck here
for (int i = 0, a = 1; i < data.length; i++, a++) {
connector.prepStatCreateProfile.setString(a, data[i]);
}
//store LOB
connector.prepStatCreateProfile.setBlob(11, logoBlob);
} catch (SQLException ex) {
ex.printStackTrace();
}
return connector.prepStatCreateProfile;
}
Is there a way to convert from my current object (imageview),image) into byte[]?, or shoud i start to think about using other class for my image/ alternatively point to the location with reference and work with paths/urls?
try this one:
BufferedImage bImage = SwingFXUtils.fromFXImage(logo.getImage(), null);
ByteArrayOutputStream s = new ByteArrayOutputStream();
ImageIO.write(bImage, "png", s);
byte[] res = s.toByteArray();
s.close(); //especially if you are using a different output stream.
should work depending on the logo class
you need to specify a format while writing and reading, and as far as I remember bmp is not supported so you will end up with a png byte array on the database
pure java fx solution trace ( == you will have to fill in missing points :)
Image i = logo.getImage();
PixelReader pr = i.getPixelReader();
PixelFormat f = pr.getPixelFormat();
WriteablePixelFromat wf = f.getIntArgbInstance(); //???
int[] buffer = new int[size as desumed from the format f, should be i.width*i.height*4];
pr.getPixels(int 0, int 0, int i.width, i.height, wf, buffer, 0, 0);
Lorenzo's answer is correct, this answer just examines efficiency and portability aspects.
Depending on the image type and storage requirements, it may be efficient to convert the image to a compressed format for storage, for example:
ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
ImageIO.write(SwingFXUtils.fromFXImage(fxImage, null), "png", byteOutput);
Blob logoBlob = connector.connection.createBlob();
logoBlob.setBytes(0, byteOutput.toByteArray());
Another advantage of doing a conversion to a common format like png before persisting the image is that other programs which deal with the database would be able to read the image without trying to convert it from a JavaFX specific byte array storage format.

How to retrieve image from pointer using java/Jna

i want to retrieve a scanned image from a Pointer. i have the front image which is a PointerByReference, i used a buffer for that :
Pointer p = frontimg.getValue();
byte[] buffer = p.getByteArray(0, frontimg.getValue().SIZE);
System.out.println(buffer);
when i use to read the image, it seems to be Null.
BufferedImage img = ImageIO.read(new ByteArrayInputStream(buffer));
so i can't write it of course:
ImageIO.write(img, "BMP", new File("D:\test.bmp"));
so please, what kind of method i have to use to proceed ?

How to write an 8 bit grey scale tiff with Java?

I am trying to write a grey scale image to an TIFF file using Sanselan. Obviously would like the save the data to be 8 bit grey scale file but somehow I always end up with a 24 bit colour file.
I have searched for file formats in general and ExifTagConstants.EXIF_TAG_PIXEL_FORMAT in particular but was unable to find anything helpful.
I also considered colour profiles but there seem to be none for grey scale images. But then they all have wacky names — I might just have overlooked the right one.
Or do I have to use a different library?
Here the code I use (without business logic and experimental stuff:
Test_Only_Sanselan:
try
{
final Map <String, Object> parameter = new HashMap <>();
parameter.put(org.apache.sanselan.SanselanConstants.PARAM_KEY_COMPRESSION,
org.apache.sanselan.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_UNCOMPRESSED);
final java.io.OutputStream output = new java.io.FileOutputStream("Test-1.tiff");
org.apache.sanselan.Sanselan.writeImage(image, output,
org.apache.sanselan.ImageFormat.IMAGE_FORMAT_TIFF, parameter);
output.close();
}
catch (final IOException exception)
{
LdfImage.log.info("! Could not create tiff image.", exception);
}
catch (final org.apache.sanselan.ImageWriteException exception)
{
LdfImage.log.info("! Could not create tiff image.", exception);
}
I wonder if I need to add a special parameter. But I have not found a useful parameter yet.
The following is a test of the Java 7 image writer which creates a correct grey scale image. But as PNG and not TIFF:
Test_Only_Java_7:
try
{
final java.util.Iterator imageWriters = javax.imageio.ImageIO.getImageWritersByMIMEType ("image/png");
final javax.imageio.ImageWriter imageWriter = (javax.imageio.ImageWriter) imageWriters.next();
final java.io.File file = new java.io.File("Test-2.png");
final javax.imageio.stream.ImageOutputStream output = javax.imageio.ImageIO.createImageOutputStream(file);
imageWriter.setOutput(output);
imageWriter.write(image);
}
catch (final IOException exception)
{
LdfImage.log.info("! Could not create tiff image.", exception);
}
Is there a TIFF pug-in for imageio?
I'm not familiar with Sanselan but I see there is a ImageInfo.COLOR_TYPE_GRAYSCALE constant, I'm guessing it could be used in the params parameter map given to writeImage.
I didn't find the javadoc for Sanselan, their link is broken, would you have one more up-to-date?
If you want to use JAI you can get your inspiration here:
void get8bitImage(byte[] data, int width, int height) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
byte[] rasterData = ((DataBufferByte)image.getRaster().getDataBuffer()).getData();
System.arraycopy(pixels, 0, rasterData, 0, pixels.length); // A LOT faster than 'setData()'
}
void main(String[] argv) {
TIFFEncodeParam ep = new TIFFEncodeParam();
FileOutputStream out = new FileOutputStream("c:\\test.tiff");
BufferedImage img = get8bitImage(myData);
ImageEncoder encoder = ImageCodec.createImageEncoder("tiff", out, ep);
encoder.encode(img);
}
Be sure that the BufferedImage has BufferedImage.TYPE_BYTE_GRAY as imageType.

Converting PNG into JPEG

I'm having problems converting a simple PNG into a JPEG format.
I'm using the following code:
...
File png = new File(filePath);
try {
SeekableStream s = new FileSeekableStream(png);
PNGDecodeParam pngParams = new PNGDecodeParam();
ImageDecoder dec = ImageCodec.createImageDecoder("png", s, pngParams);
RenderedImage pngImage = dec.decodeAsRenderedImage();
JPEGEncodeParam jparam = new JPEGEncodeParam();
jparam.setQuality(0.50f); // e.g. 0.25f
File jpeg = new File("jpeg.jpeg");
FileOutputStream out = new FileOutputStream(jpeg);
ImageEncoder encoder = ImageCodec.createImageEncoder("JPEG", out, jparam);
encoder.encode(pngImage);
s.close();
} catch (IOException e) {
ok = false;
e.printStackTrace();
}
return ok;
}
...
I end up with an JAI exception ->
java.lang.RuntimeException: Only 1, or 3-band byte data may be written.
at com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:148) ...
Ran out of options. Any suggestion?
It might be easier to use ImageIO to read the PNG into a BufferedImage and write the image out in JPEG format.
Addendum: In this approach, the conversion is handled transparently by the writer's ImageTranscoder.
BufferedImage img = ImageIO.read(new File("image.png"));
ImageIO.write(img, "jpg", new File("image.jpg"));
you probably have alpha channel in the png that you need to get rid of before trying to write the jpg.
Create a new BufferedImage with type TYPE_INT_RGB (not TYPE_INT_ARGB), and then write your source image (pngImage) onto the new blank image.
Something like this (warning, not tested code):
BufferedImage newImage = new BufferedImage( pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_INT_RGB);
newImage.createGraphics().drawImage( pngImage, 0, 0, Color.BLACK, null);
I also found that reading a PNG image into a BufferedImage with ImageIO (Java 6) and writing it out to a JPG "format name" corrupted the image. The image was there, but the colors looked "solarized" and almost inverted. The JPG file was much smaller than the PNG file for sure, so a lot of compression was done. I don't see how you might control the compression or color depth.
I had corrupted file after conversion with other solutions but this method worked for me:
public static void formatConverter(String pngFile, String jpgFile) {
try {
File input = new File(pngFile);
File output = new File(jpgFile);
BufferedImage image = ImageIO.read(input);
BufferedImage result = new BufferedImage(
image.getWidth(),
image.getHeight(),
BufferedImage.TYPE_INT_RGB);
result.createGraphics().drawImage(image, 0, 0, Color.WHITE, null);
ImageIO.write(result, "jpg", output);
} catch (IOException e) {
e.printStackTrace();
}
}
I suppse that JAI reads the PNG image with an indexed colour model and is only able to write 8-bit grayscale or 24-bit colour images as JPEG files.
If you are not required to use JAI for this task, you should be able to use ImageIO instead:
ImageIO.write(ImageIO.read(new File("in.png")), "JPEG", new File("out.jpg"));
I was getting the following message in a slightly different context. Getting rid of the alpha channel solved the problem
javax.imageio.IIOException: Sample size must be <= 8
at com.sun.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.java:435)
at javax.imageio.ImageWriter.write(ImageWriter.java:580)
at com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageWriter.write(Unknown Source)
at net.sf.basedb.util.ImageTools.tiffToJpg(ImageTools.java:98)
at net.sf.basedb.util.ImageTools.main(ImageTools.java:118)
see Converting transparent gif / png to jpeg using java
Have a look at the solution that redraws with the graphics environment posted by harmanjd. The solution with the DirectColorModel doesn't compile and should be wiped away. I don't have enough rep points to comment directly there.

Categories

Resources