Convert Tif image to byte[] - java

I tried to convert Tiff image to Byte[] but getting exception from java 1.8 sdk. I searched in google but did not get solution yet. Same code works for java 1.6.
public static byte[] convertImage(String dirName, String imageName)
{
try
{
//String dirName="C:\\Temp\\";
ByteArrayOutputStream baos=new ByteArrayOutputStream(1000);
BufferedImage img=ImageIO.read(new File(dirName,imageName));
ImageIO.write(img, "tif", baos);
baos.flush();
byte[] bytearray = baos.toByteArray();
baos.close();
return bytearray;
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception ex)
{
ex.printStackTrace();
}
return null;
}
variable img is always null in java 1.8 but 1.6 returns info.
Exception raised from sdk 1.8 as follows
java.lang.IllegalArgumentException: image == null!
at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(Unknown Source)
at javax.imageio.ImageIO.getWriter(Unknown Source)
at javax.imageio.ImageIO.write(Unknown Source)
at test.practice.net.ConverterImageUsing18.convertImage(ConverterImageUsing18.java:88)
at test.practice.net.ConverterImageUsing18.GetBase64BinaryAsString(ConverterImageUsing18.java:52)
at test.practice.net.ConverterImageUsing18.main(ConverterImageUsing18.java:42)
Any hits or sample code is appreciable.

ImageIO needs an additional plugin to read or write TIFF. The built-in formats are BMP, GIF, JPEG, PNG and WBMP. To read or write TIFF, you can use JAI (jai_imageio.jar), TwelveMonkeys ImageIO or similar.
Without a suitable plugin, ImageIO.read(...) simply returns null. This is the most likely reason why your img is null (and you get an exception). You might have JAI or similar installed in your Java 1.6 JRE, or you may be testing with a different file.
However, if you just want to get the bytes of the original file, there's no need to use ImageIO at all. Simply read the bytes from the file into a byte array, for example like this:
File file = new File(dirName, imageName);
int length = (int) file.length();
byte[] bytes = new byte[length];
try (DataInputStream input = new DataInputStream(new FileInputStream(file))) {
input.readFully(bytes);
}
Or in Java 8, you can write it more elegant (thanks, #JoopEggen):
File file = new File(dirName, imageName);
byte[] bytes = Files.readAllBytes(file.toPath());

Related

can't create a image file from BASE64

Well, i'm trying to send a picture from android to java, if i make it with compression it works really good, but i need to make it without compression beacuse i need a good or normal quality.
FixBitmap is my current Bitmap picture
//Android
FixBitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byteArray = byteArrayOutputStream.toByteArray();
ConvertImage = Base64.encodeToString(byteArray, Base64.DEFAULT);
Log.e(TAG,"LENGTH"+ConvertImage.length());
Length 43388
//Java
try{
String file=request.getParameter("image_data");
String filename=rt.getId()+"_"+rt.getName()+".png";
BufferedImage image = null;
byte[] imageByte;
BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(file);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
File outputfile = new File(filename);
ImageIO.write(image, "png", outputfile);
Path destinationFile = Paths.get(getServletContext().getRealPath("/")+"uploads\\", filename);
Files.write(destinationFile,imageByte);
}catch(Exception ex){
System.out.println("Error :"+ex.getMessage());
}
This code actually works as i said, but the compression make it looks in a very bad quality, so i tried to make it without compression, just converting my bitmap to a byte array, just like this
ByteBuffer buffer = ByteBuffer.allocate(FixBitmap.getRowBytes() *
FixBitmap.getHeight());
FixBitmap.copyPixelsToBuffer(buffer);
byteArray = buffer.array();
ConvertImage = Base64.encodeToString(byteArray, Base64.DEFAULT);
Log.e(TAG,"LENGTH"+ConvertImage.length());
Length 252107
The code on my java side it's the same but now it doesn't work, it just shows me this error :
java.lang.IllegalArgumentException: image == null!
So I decided to print the length because maybe there is some restrictions about this...
so I hope you can help me with this (just send/get the picture without compression)

Liferay DLFileEntry image conversion is not fully converting the image

I am converting an image as a DLFileEntry from JPG to PNG format using the following code.
try {
DLFileEntry dlFileEntry = DLFileEntryServiceUtil.getFileEntry(dlFileEntryId);
InputStream inputStream = dlFileEntry.getContentStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[1024];
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
byte[] byteArray = buffer.toByteArray();
ImageBag imageBag = ImageToolUtil.read(byteArray);
RenderedImage renderedImage = imageBag.getRenderedImage();
if (renderedImage == null) {
throw new IOException("Unable to decode image");
}
renderedImage = ImageToolUtil.scale(renderedImage, 2000);
buffer = new ByteArrayOutputStream();
ImageIO.write(renderedImage, "png", buffer);
InputStream fis = new ByteArrayInputStream(buffer.toByteArray());
DLAppServiceUtil.updateFileEntry(
dlFileEntry.getFileEntryId(),
dlFileEntry.getName(),
MediaType.IMAGE_PNG_VALUE,
dlFileEntry.getTitle(),
dlFileEntry.getDescription(),
"",
true,
fis,
buffer.size(),
serviceContext);
} catch (Exception e) {
e.printStackTrace();
}
Even though it updates the image content type and extension in "Documents and Media", when we try downloading the image, it is still in JPG format.
The image looks like above in Documents and Media. You can see that the content type has become image/png.
Above shows the screenshot while I tried to Download this image and save it. It is still in the original format of JPG when I try downloading. What should I do in addition to the code above, inorder to completely convert the image to PNG?
You still store the old file name: dlFileEntry.getName()
I would guess that jpeg or jpg is the extension of the old file name and the browser determines his file filter from the extension.
So better exchange the extension as well:
DLAppServiceUtil.updateFileEntry(
dlFileEntry.getFileEntryId(),
dlFileEntry.getName().replaceAll("\\..*?$",".png"),
...
This will change the extension that is stored for that file

Error while converting image to byte[] in Java using WritableRaster and DataBufferByte.

I am trying to convert image to byte[] using code
public static byte[] extractBytes(String ImageName) throws IOException {
// open image
File imgPath = new File(ImageName);
BufferedImage bufferedImage = ImageIO.read(imgPath);
// get DataBufferBytes from Raster
WritableRaster raster = bufferedImage.getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
return (data.getData());
}
When I am testing it using code
public static void main(String[] args) throws IOException {
String filepath = "image_old.jpg";
byte[] data = extractBytes(filepath);
System.out.println(data.length);
BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
File outputfile = new File("image_new.jpg");
ImageIO.write(img, "jpeg", outputfile);
}
I am getting data.length = 4665600 and getting error
Exception in thread "main" java.lang.IllegalArgumentException: image == null!
at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925)
at javax.imageio.ImageIO.getWriter(ImageIO.java:1591)
at javax.imageio.ImageIO.write(ImageIO.java:1520)
at com.medianet.hello.HbaseUtil.main(HbaseUtil.java:138)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
But when I am changing my extractBytes code to
public static byte[] extractBytes (String ImageName) throws IOException {
ByteArrayOutputStream baos=new ByteArrayOutputStream();
BufferedImage img=ImageIO.read(new File(ImageName));
ImageIO.write(img, "jpg", baos);
baos.flush();
return baos.toByteArray();
}
I am getting data.length = 120905 and getting success(image.jpg getting created in the desired location)
The thing is, the first version of extractBytes reads an image, and just returns the image's pixels as an array of bytes (assuming it uses DataBufferByte). These bytes are not in a file format, and are useless without extra information, such as width, height, color space etc. ImageIO can't read these bytes back, and because of this, null is returned (and assigned to img, later causing an IllegalArgumentException from ImageIO.write(...)).
The second version decodes the image, then encodes it again in JPEG format. This is a format ImageIO will be able to read, and you get an image (assigned to img) as you expect.
However, you code seems like just a very, very CPU-expensive way of copying images (you decode an image, then encode, then decode again, before finally encoding)... For JPEG files this decode/encode cycle will also degrade the image quality. Unless you are planning to use the image data for anything, and just want to copy an image from one place to another, don't use ImageIO and BufferedImages. These types are intended for image manipulation.
Here's a modified version of your main method:
public static void main(String[] args) throws IOException {
byte[] buffer = new byte[1024];
File inFile = new File("image_old.jpg");
File outFile = new File("image_new.jpg");
InputStream in = new FileInputStream(inFile);
try {
OutputStream out = new FileOutputStream(outFile);
try {
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
}
finally {
out.close();
}
}
finally {
in.close();
}
}
(It's possible to write this better/more elegant using try-with-resources in Java 7, or NIO2 Files.copy in Java 8, but I leave that to you. :-) )

Java Converting ByteArray into Image

I'm reading a file that has an array of bytes. I downloaded the Apache Commons IO library to use the FileUtils' method readFileToByteArray
File file = new File("/home/username/array.txt");
FileUtils fu = new FileUtils();
byte[] array = FileUtils.readFileToByteArray(file);
I want to convert the array of bytes to an Image.
ByteArrayInputStream bis = new ByteArrayInputStream(array);
Iterator<?> readers = ImageIO.getImageReadersByFormatName("gif");
ImageReader reader = (ImageReader) readers.next();
Object source = bis;
ImageInputStream iis = ImageIO.createImageInputStream(source);
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
Image image = reader.read(0, param); // this line is the problem
When the code goes to the referred line, it throws an Exception saying
javax.imageio.IIOException: Unexpected block type 128!
I don't know what this exception means, therefore, I don't know how to fix it.
Any further information that could be helpful just need to be requested.
Thanks
I've tried your code on this file and it works fine.
What's the format of your array.txt? readFileToByteArray() expects a binary format, and your image reader will further expect it to be a GIF file.
Once you have byte[] you can use ImageIO to write it to BufferedImage.
BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(array));
ImageIO.write(bImageFromConvert, "gif", new File("c:/test.gif"));
That code means the reader couldn't decipher the metadata on the image file. Make sure the right file is getting read and it's well formed. Or it may be expecting a different file type.
without byte[] i feel this will be good for multipart file transfer,for this we need apache common jar files
final FileOutputStream output = new FileOutputStream("D:\\Dir\\"+ request.getParameter("imageName") + ".jpg");
IOUtils.copy(request.getPart("file").getInputStream(), output);
output.close();

streaming a jpeg using com.sun.image.codec.jpeg.JPEGImageEncoder vs javax.imageio.ImageIO

I have a BufferedImage object of a jpeg which needs to be streamed as servlet response.
The existing code streams the jpeg using JPEGImageEncoder which looks like this :
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(resp.getOutputStream());
resp.reset();
resp.setContentType("image/jpg");
resp.setHeader("Content-disposition", "inline;filename=xyz.jpg");
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image);
param.setQuality(jpegQuality, false);
encoder.setJPEGEncodeParam(param);
encoder.encode(image);
I have noticed that this is resulting in the file size of the streamed jpeg to be tripled , unable to figure why.So I have tried using ImageIO to stream the jpeg
ImageIO.write(image, "jpg", out);
This works just fine, I am unable to decide why my predecessor has gone with the choice of JPEGImageEncoder and was wondering what issues would arise if I change to using ImageIO, I have compared both jpegs and couldn't really spot differences. Any thoughts?
To be clear, you've already a concrete JPEG image somewhere on disk or in database and you just need to send it unmodified to the client? There's then indeed absolutely no reason to use JPEGImageEncoder (and ImageIO).
Just stream it unmodified to the response body.
E.g.
File file = new File("/path/to/image.jpg");
response.setContentType("image/jpeg");
response.setHeader("Content-Length", String.valueOf(file.length()));
InputStream input = new FileInputStream(file);
OutputStream output = response.getOutputStream();
byte[] buffer = new byte[8192];
try {
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
}
finally {
try { input.close(); } catch (IOException ignore) {}
try { output.close(); } catch (IOException ignore) {}
}
You see the mistake of unnecessarily using JPEGImageEncoder (and ImageIO) to stream image files often back in code of starters who are ignorant about the nature of bits and bytes. Those tools are only useful if you want to convert between JPEG and a different image format, or want to manipulate (crop, skew, rotate, resize, etc) it.

Categories