Converting Buffered Image to MultipartFile - java

Using Spring MVC & JSP
My scenario-
User uploads image file (gif,jpg,png) and if the file doesnt match dimensions then file needs to be scaled and disaply on jsp as preview.
I have MultipartFile(which is uploaded file), I convert that into BufferedImage then I resize the BufferedImage using Graphics2D. I want to convert this buffered image into multipart file again to show it on jsp.
How Can i convert buffered image into MultipartFile?
Thanks

I doubt this statement is correct: I want to convert this buffered image into multipart file again to show it on jsp
To my knowledge you need to either:
Write the converted image into a disk and display it using html <img..> tag, or
Create a spring mvc handler method that writes the image into the response body directly, something like this
.
#RequestMapping(..)
public void convertedImg(HttpServletResponse resp) {
// set response Content-Type..
OutputStream os = resp.getOutputStream();
//.. write your converted image into os
}

You can probably use ImageIO to write your BufferedImage to some file format.
Like:
BufferedImage image; // your image
OutputStream stream; // your output
try {
ImageIO.write(image, "png", stream);
}
finally {
stream.flush();
}
Where stream can be a FileOutputStream to the server's file system, the OutputStream of a database blob, or the servlet response's OutputStream, depending on where/if you want to store it.

Related

GIF image only partially displayed

I got a strange issue with a GIF image in Java. The image is provided by an XML API as Base64 encoded string. To decode the Base64, I use the commons-codec library in version 1.13.
When I just decode the Base64 string and write the bytes out to a file, the image shows properly in browsers and MS Paint (nothing else to test here).
final String base64Gif = "[Base64 as provided by API]";
final byte[] sigImg = Base64.decodeBase64(base64Gif);
File sigGif = new File("C:/Temp/pod_1Z12345E5991872040.org.gif");
try (FileOutputStream fos = new FileOutputStream()) {
fos.write(sigImg);
fos.flush();
}
The resulting file opened in MS Paint:
But when I now start consuming this file using Java (for example creating a PDF document from HTML using the openhtmltopdf library), it is corrupted and does not show properly.
final String htmlLetterStr = "[HTML as provided by API]";
final Document doc = Jsoup.parse(htmlLetterStr);
try (FileOutputStream fos = new FileOutputStream(new File("C:/Temp/letter_1Z12345E5991872040.pdf"))) {
PdfRendererBuilder builder = new PdfRendererBuilder();
builder.useFastMode();
builder.withW3cDocument(new W3CDom().fromJsoup(doc), "file:///C:/Temp/");
builder.toStream(fos);
builder.useDefaultPageSize(210, 297, BaseRendererBuilder.PageSizeUnits.MM);
builder.run();
fos.flush();
}
When I now open the resulting PDF, the image created above looks like this. It seems that only the first pixel lines are printed, some layer is missing, or something like that.
The same happens, if I read the image again with ImageIO and try to convert it into PNG. The resulting PNG looks exactly the same as the image printed in the PDF document.
How can I get the image to display properly in the PDF document?
Edit:
Link to original GIF Base64 as provided by API: https://pastebin.com/sYJv6j0h
As #haraldK pointed out in the comments, the GIF file provided via the XML API does not conform to the GIF standard and thus cannot be parsed by Java's ImageIO API.
Since there does not seem to exist a pure Java tool to repair the file, the workaround I came up with now is to use ImageMagick via Java's Process API. Calling the convert command with the -coalesce option will parse the broken GIF and create a new one that does conform to the GIF standard.
// Decode broken GIF image and write to disk
final String base64Gif = "[Base64 as provided by API]";
final byte[] sigImg = Base64.decodeBase64(base64Gif);
Path gifPath = Paths.get("C:/Temp/pod_1Z12345E5991872040.tmp.gif");
if (!Files.exists(gifPath)) {
Files.createFile(gifPath);
}
Files.write(gifPath, sigImg, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
// Use the Java Process API to call ImageMagick (on Linux you would use the 'convert' binary)
ProcessBuilder procBuild = new ProcessBuilder();
procBuild.command("C:\\Program Files\\ImageMagick-7.0.9-Q16\\magick.exe", "C:\\Temp\\pod_1Z12345E5991872040.tmp.gif", "-coalesce", "C:\\Temp\\pod_1Z12345E5991872040.gif");
Process proc = procBuild.start();
// Wait for ImageMagick to complete its work
proc.waitFor();
The newly created file can be read by Java's ImageIO API and be used as expected.

Create gif from Servlett outputstream in Java

I am developing an application on a server to manage some Image showing stuff. Therefor I created a servlett to put an Image from a Directory into an outputstream so I can call it from my jsp to display the Image.
BufferedImage bi;
bi = ImageIO.read(new URL(imagePath));
OutputStream out = response.getOutputStream();
ImageIO.write(bi, "jpg", out);
out.close();
this part works fine. Now I thought it would be nice to get a Stream of Images and combine them to a .gif file and to show the .gif in my .jsp too.
In this Link http://elliot.kroo.net/software/java/GifSequenceWriter/GifSequenceWriter.java
I found an example that should work(I hope so).
So I want to change this solution a little bit.I created another servlett where I do a for-loop on a hashmap and every time I want to pass the showimage the Id of the Image that I want.
for(Map.Entry<Integer, Integer> entry : mMap.entrySet())
{
response.sendRedirect(request.getContextPath() + "/showimage?
imageid="+entry.getValue());
}
After that, my showImage servlett stores the Image as .jpg in the outputstream. In the next step, within my for loop I want to get the image outputstream and use the writeSequence function.
Can anyone tell me how to get the image from the Outputstream? Or is the Outputstream sent straight back to client and this isn't even possible without copying the imageshow code in the new class?
Thank you very much

Save lowagie.text.Image to File

I have com.lowagie.text.Image Object and I want to save it to a file as PNG image.
I wonder whether it is possible or not to save it as a image file.I googled it but no luck. Anybody know how to save itext Image object to file?
P.S: I am not bothered about writing the Image object to PDF. I just want to save it as a image file(like png,jpg etc).
If you know that your image was originally a PNG, you can just save the result of getOriginalData() to a file. Otherwise, you can build a BufferedImage first:
byte[] data = image.getOriginalData();
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(data));
ImageIO.write(bi, "PNG", file);

How to read Bytes of an Image in Java?

I am currently working with Image processing in Java. Initially I used ImageIO class to write images
ImageIO.write(image,"jpg",os);
the problem with this method is am lossing the actual image size and quality. Then I preferred ByteStream
Files.readAllBytes(fi.toPath());
to read and
fos.write(fileContent);
to write Images. This works perfectly. The issue I am facing here is I can read only files but not Images(ie, BuffreredImage image). Is it possible to read a Image rather than files here or should I move to someother IO?
Code Snippet is here,
try {
File fnew=new File("d:\\3\\IMG1.jpg");
java.io.FileOutputStream fos = new java.io.FileOutputStream(new File("d:\\3\\Test1\\4.jpg"));
File fi = new File("d:\\3\\7.jpg");
byte[] fileContent = Files.readAllBytes(fi.toPath());
fos.write(fileContent);
} catch (Exception e) {
System.out.println("Exception");
}
Any Kind of suggestions or help will be appreciated. Thanks in Advance.
the problem with this method is am lossing the actual image size and quality. Then I preferred ByteStream
When you read a JPEG with with ImageIO, it is converting the JPEG to a Bitmap automatically. Then when you write it, it is encoding to a JPEG again (which loses quality).
Just replace ImageIO.write(image,"jpg",os) with ImageIO.write(image,"png",os) and you are done. A lossless format such as PNG will not lose any data when you write the image.
BufferedImage getRGB() will get you all the actual pixel data for the image. There will be no compression or anything like JPEG. It will be the raw image.
Edited to add an example based on my comments...
BufferedImage image = ImageIO.read(new File("google.jpg"));
ImageWriter w = ImageIO.getImageWritersBySuffix("jpg").next();
ImageOutputStream out = ImageIO.createImageOutputStream(new File("output.jpg"));
w.setOutput(out);
ImageWriteParam param = new JPEGImageWriteParam(Locale.getDefault());
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(1);
w.write(null, new IIOImage(image, null, null), param);
out.close();

Not able to delete image file after image conversion from PNG to TIF

I am creating .PNG file using BufferedImage with some test. Now after creating image I am trying to convert .PNG image to .TIF, which is working fine. Now once I create TIF image, I want to delete PNG image. But because of some reason, I am not able to do this. There is no any exception for this.
Here is my code
File pngFile = null;
FileOutputStream fOut = null;
try {
pngFile = new File("C:\\Test.PNG");
fOut = new FileOutputStream ("C:\\Test.TIF");
RenderedOp src = JAI.create("fileload", "C:\\Test.PNG");
TIFFImageEncoder encoder = new TIFFImageEncoder (fOut, null);
encoder.encode (src);
}catch(Exception e) {
}finally {
fOut.close();
System.out.println(pngFile.delete());
}
Well there's definitely no exception since your catch block is empty.
Something may be still holding a handle to the file, not allowing it to be deleted.
I would examine JAI.create, RenderedOp and the TiffEncoder.
Instead of providing the file path as string you can provide input stream and in finally first close the input stream and then delete the file. This may work.
I was facing same problem sometime before. The best way to do it in this is to first dispose the resources using the image object you have create, like below-
var image = Image.FromFile(pngTarget); // here pngTarget is my PNG file's name along with complete path.
// your code to convert png to tiff
.
.
.
at the end of the method you can write below -
image.Dispose(); // the image object I have created above
File.Delete(pngTarget); // delete the file
Also, don't forget to flush/close the memory stream, if using any.
Thanks.

Categories