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();
Related
I am uploading a jpg to a spring controller endpoint. The image is uploaded as Base64 image/jpg which comes in as a MultipartFile. I am decoding the inputstream using Base64Decoder which seems to decode it ok but when I turn it into an InputStream to write it out to disk I can see it's been modified (according to what I can see in the debugger). When I save the file and open it it says it's an unsupported file type.
I took the multipart inputstream and wrote it directly to disk and I see the base64 encoding in notepad.
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4QBgRXhpZgAASUkqAAgAAAACADEBAgAHAAAAJgAAAGmHBAABAAAALgAAAAAAAABHb29nbGUAAAMAAJAHAAQAAAAwMjIwAqAEAAEAAAAACAAAA6AEAAEAAAAABgAAAAAAAP/bAIQAAwICCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCggKCgoKCgoICAgKCgoICAgICgoICAgKCgoICA0NCggNCAgKCAEDBAQGBQYIBgYICA0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI/8AAEQgGAAgAAwEiAAIRAQMRAf/EAB0AAAIDAQEBAQEAAAAAAAAAAAMEAgUGAQAHCAn/xABJEAABAwIDBgQFBAIBAwMCAA8BAAIRAyEEMUEFElFhcfAGgZGhEyKxwdEHMuHxFEJSFSNiCDNyFoKSFyRDU6LCCTRjRHOy0uL/xAAbAQEBAQEBAQEBAAAAAAAAAAAAAQIDBAUGB//EACoRAQEBAQACAwADAAEEAwEBAQABEQIDcRIhMQQTsVEUIjJBBWGBwUIj/9oADAMBAAIRAxEAPwCgrFsRw4ZfWEs2FXUN4C7p4c10702ML4/M+p6jhzfqep/i4p0uS9Vtw8vddwRkX7t+ck1TdElWusVNVsRY3K1ngx2YFsz5rMYytJHX+7rSeDWGf6XHqf8A0938eZ02zK8LlWoMzwP9LwCV2jxC81j7kswTAYsE2Xto1OAzVPslvzHT8K8LV
Here's my controller and my code:
#PostMapping(value = "/saveBlueprintOrder")
public ResponseEntity<?> saveBlueprintOrder(#RequestParam MultipartFile blueprint,
#RequestParam(required = false) MultipartFile coversheet,
#RequestParam(required = false) MultipartFile logo,
#ModelAttribute BlueprintOrder blueprintOrder) {
if(coversheet != null) {
BASE64Decoder decoder1 = new BASE64Decoder();
byte[] imageBytes = decoder1.decodeBuffer(coversheet.getInputStream());
InputStream bis = new ByteArrayInputStream(imageBytes);
BufferedImage image = ImageIO.read(bis);
ImageIO.write(image, "jpg", new File("C:\\Users\\i58287\\Downloads\\coversheet.jpg"));
OutputStream stream = new FileOutputStream("C:\\Users\\i58287\\Downloads\\coversheet-test.jpg");
stream.write(imageBytes);
stream.close();
I just need to be able to translate this image to an inputstream so I can check the image locally in addition I need to send it to another api as such. What am I missing that's causing this image to be un-openable? Thanks for any help!
PS: I've done a lot of combinations so this is showing a couple options I have tried, BufferedImage image = ImageIO.read(bis) keeps returning a null image.
Ok so I don't know WHY this is what I had to do but I ended up saving my byte[] as a String and cut off the pre-pended
data:image/jpeg;base64
Then I decoded it into an InputStream. Anyone know why I had to do this?
Here's the code:
String imageBytes = new String(coversheet.getBytes(), StandardCharsets.UTF_8);
String imageDataBytes = imageBytes.substring(imageBytes.indexOf(",") + 1);
InputStream stream = new ByteArrayInputStream(Base64.getDecoder().decode(imageDataBytes.getBytes()));
BufferedImage image = ImageIO.read(stream);
ImageIO.write(image, "jpg", new File("C:\\Users\\i58287\\Downloads\\coversheet-test.jpg"));
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());
My task is to take one GeoTIFF, make some image segmentation on in, and save it to new GeoTIFF(with existing coordinates). If I understand correctly, the coordinates are preserved in GeoTIFF metadata.
So I grab metadata from the original file:
File file = new File(inputFilePath);
ImageInputStream iis = ImageIO.createImageInputStream(file);
Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
IIOMetadata metadata=null;
ImageReader reader=null;
if (readers.hasNext()) {
// pick the first available ImageReader
reader = readers.next();
// attach source to the reader
reader.setInput(iis, true);
// read metadata of first image
metadata = reader.getImageMetadata(0);
}
And when I do
System.out.println("Metadata: "+metadata);, I see the correct XML tree of metatags.
So I'm do some magic with image
System.out.println("Starting segmentation");
BufferedImage image = UtilImageIO.loadImage(inputImage);
// Select input image type. Some algorithms behave different depending on image type
ImageType<MultiSpectral<ImageFloat32>> imageType = ImageType.ms(3, ImageFloat32.class);
ImageSuperpixels alg = FactoryImageSegmentation.fh04(new ConfigFh04(500, 30), imageType);
// Convert image into BoofCV format
ImageBase color = imageType.createImage(image.getWidth(), image.getHeight());
ConvertBufferedImage.convertFrom(image, color, true);
// Segment and display results
performSegmentation(alg, color);
System.out.println("Segmentation finished");
In result I obtain a BufferedImage(resultBufferedImage) with successfully image segmentation.
And here starts my problems, I'm trying to save this BufferedImage with old metadata:
BufferedOutputStream out;
ImageWriter writer = ImageIO.getImageWriter(reader);
ImageOutputStream imgout = null;
FileOutputStream fos =null;
fos = new FileOutputStream(outputImage);
out = new BufferedOutputStream(fos);
imgout = ImageIO.createImageOutputStream(out);
writer.setOutput(imgout);
ImageWriteParam param = writer.getDefaultWriteParam();
IIOImage destIIOImage = new IIOImage(resultBufferedImage, null, metadata);
System.out.println("Before write");
writer.write(null, destIIOImage, null);
System.out.println("After write");
I get printed "After write". But program is still running, I tried to wait, but no results. So when I kill process the file is created successfully, even with geodata. How can I determine the finish of writing and stop program?
p.s. Image in default Ubuntu viewer seems to be nice, but when I opened it in QGIS I have transparent fields, and how can I make gray background transparent?
Not a real answer, but here's two answers on how to make a TIFF transparent:
QGis problem with raster transparent
How to make transparent the background of a topographic map in QGis 1.8.0?
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.
I'm trying to create a BufferedImage from a ByteArrayInputStream with:
byte[] imageData = getData(imageFile); // returns file as byte[]
InputStream inputStream = new ByteArrayInputStream(imageData);
String format = getFormatName(inputStream);
BufferedImage img = ImageIO.read(inputStream);
But img is always null. The input stream is valid (since I use it before to get the image format).
What could be making ImageIO return null? Do I need to use flush or close in any place?
Your call to getFormatName consumes the inputStream, so the stream pointer is at the end of the byte array. Any try to read from that stream will tell that it's at the end of the 'file'. You need to reset the stream (or create a new one) before you hand it over to the ImageIO.read() method:
String format = getFormatName(new ByteArrayInputStream(imageData));
BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageData));