Write Base64-encoded image to file - java

How to write a Base64-encoded image to file?
I have encoded an image to a string using Base64.
First, I read the file, then convert it to a byte array and then apply Base64 encoding to convert the image to a string.
Now my problem is how to decode it.
byte dearr[] = Base64.decodeBase64(crntImage);
File outF = new File("c:/decode/abc.bmp");
BufferedImage img02 = ImageIO.write(img02, "bmp", outF);
The variable crntImage contains the string representation of the image.

Assuming the image data is already in the format you want, you don't need ImageIO at all - you just need to write the data to the file:
// Note preferred way of declaring an array variable
byte[] data = Base64.decodeBase64(crntImage);
try (OutputStream stream = new FileOutputStream("c:/decode/abc.bmp")) {
stream.write(data);
}
(I'm assuming you're using Java 7 here - if not, you'll need to write a manual try/finally statement to close the stream.)
If the image data isn't in the format you want, you'll need to give more details.

With Java 8's Base64 API
byte[] decodedImg = Base64.getDecoder()
.decode(encodedImg.getBytes(StandardCharsets.UTF_8));
Path destinationFile = Paths.get("/path/to/imageDir", "myImage.jpg");
Files.write(destinationFile, decodedImg);
If your encoded image starts with something like data:image/png;base64,iVBORw0..., you'll have to remove the part. See this answer for an easy way to do that.

No need to use BufferedImage, as you already have the image file in a byte array
byte dearr[] = Base64.decodeBase64(crntImage);
FileOutputStream fos = new FileOutputStream(new File("c:/decode/abc.bmp"));
fos.write(dearr);
fos.close();

import java.util.Base64;
.... Just making it clear that this answer uses the java.util.Base64 package, without using any third-party libraries.
String crntImage=<a valid base 64 string>
byte[] data = Base64.getDecoder().decode(crntImage);
try( OutputStream stream = new FileOutputStream("d:/temp/abc.pdf") )
{
stream.write(data);
}
catch (Exception e)
{
System.err.println("Couldn't write to file...");
}

Other option using apache-commons:
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
...
File file = new File( "path" );
byte[] bytes = Base64.decodeBase64( "base64" );
FileUtils.writeByteArrayToFile( file, bytes );

Try this:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
public class WriteImage
{
public static void main( String[] args )
{
BufferedImage image = null;
try {
URL url = new URL("URL_IMAGE");
image = ImageIO.read(url);
ImageIO.write(image, "jpg",new File("C:\\out.jpg"));
ImageIO.write(image, "gif",new File("C:\\out.gif"));
ImageIO.write(image, "png",new File("C:\\out.png"));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Done");
}
}

Related

Zip Archives get corrupted when uploading to Azure Blob Store using REST API

I have been really banging my head against the wall with this one, uploading text files is fine, but when I upload a zip archive into my blob store -> it gets corrupted, and cannot be opened once downloaded.
Doing a hex compare (image below) of the original versus file that has been through Azure shows some subtle replacements have happened, but I cannot find the source of the change/corruption.
I have tried forcing UTF-8/Ascii/UTF-16, but found UTF-8 is probably correct, none have resolved the issue.
I have also tried different http libraries but got the same result.
Deployment environment is forcing unirest, and cannot use the Microsoft API (Which seems to work fine).
package blobQuickstart.blobAzureApp;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Base64;
import org.junit.Test;
import kong.unirest.HttpResponse;
import kong.unirest.Unirest;
public class StackOverflowExample {
#Test
public void uploadSmallZip() throws Exception {
File testFile = new File("src/test/resources/zip/simple.zip");
String blobStore = "secretstore";
UploadedFile testUploadedFile = new UploadedFile();
testUploadedFile.setName(testFile.getName());
testUploadedFile.setFile(testFile);
String contentType = "application/zip";
String body = readFileContent(testFile);
String url = "https://" + blobStore + ".blob.core.windows.net/naratest/" + testFile.getName() + "?sv=2020-02-10&ss=b&srt=o&sp=c&se=2021-09-07T20%3A10%3A50Z&st=2021-09-07T18%3A10%3A50Z&spr=https&sig=xvQTkCQcfMTwWSP5gXeTB5vHlCh2oZXvmvL3kaXRWQg%3D";
HttpResponse<String> response = Unirest.put(url)
.header("x-ms-blob-type", "BlockBlob").header("Content-Type", contentType)
.body(body).asString();
if (!response.isSuccess()) {
System.out.println(response.getBody());
throw new Exception("Failed to Upload File! Unexpected response code: " + response.getStatus());
}
}
private static String readFileContent(File file) throws Exception {
InputStream is = new FileInputStream(file);
ByteArrayOutputStream answer = new ByteArrayOutputStream();
byte[] byteBuffer = new byte[8192];
int nbByteRead;
while ((nbByteRead = is.read(byteBuffer)) != -1)
{
answer.write(byteBuffer, 0, nbByteRead);
}
is.close();
byte[] fileContents = answer.toByteArray();
String s = Base64.getEncoder().encodeToString(fileContents);
byte[] resultBytes = Base64.getDecoder().decode(s);
String encodedContents = new String(resultBytes);
return encodedContents;
}
}
Please help!
byte[] resultBytes = Base64.getDecoder().decode(s);
String encodedContents = new String(resultBytes);
You are creating a String from a byte array containing binary data. String is only for printable characters. You do multiple pointless encoding/decoding just taking more memory.
If the content is in a ZIP format, it's binary, just return the byte array. Or you can encode the content, but then you should return the content encoded. As a weakness, you're doing it all in memory, limiting potential size of the content.
Unirest file handlers will by default force a multipart body - not supported by Azure.
A Byte Array can be provided directly as per this: https://github.com/Kong/unirest-java/issues/248
Unirest.put("http://somewhere")
.body("abc".getBytes())

Java Class to Convert images to jpeg and compress it - the input and output parameter ist an blob which includes the image itself

following problem:
I´m using an Oracle database and Apex.
In one of the websites, it is possible to upload Images to the database.
This images shoud be converted to jpeg and compressed after upload.
Until now, we used ordimage, but this database package is not longer supported in den next versions of the database.
My idea:
Create a java class which do the converting and compressing from images. This class i will upload to the oracle database. I create a wrapper procedure which and call it with the blob, which includes the image to be converted. The jave class give back the converted image as blob.
I don´t want to save the converted files temporary in filesystem!
I found a solution t convert blob to jpg.
Will this program convert every image Format ?
Convert Blob to JPG and update blob
On an other side I find a solution for compress jpeg, but not with blob as input / output:
https://examples.javacodegeeks.com/desktop-java/imageio/compress-a-jpeg-file/
I'm an absolut Java Beginner, I'm a database developer.
Do you have any tips for me?
Greetings,
Holger
Hey,
the code from https://examples.javacodegeeks.com/desktop-java/imageio/compress-a-jpeg-file/ works fine and the jpeg images are compressed.
Unfortunaly i need the class with blob as in and out parameter.
I get a jpg image from my database as blob via odbc an then call compressJPEG (myBlobCopy) with the blob.
To show what happend, i do some output in the classes.
The size of the blob before an after calling the compressJPEG is the same.
Here the output:
126 23190 myimage.jpg Length of retrieved Blob: 4284416
Length of copy Blob: 4284416
Call compressJPEG (myBlobCopy)
now in compressJPEG
Back from compressJPEG: Length of retrieved Blob: 4284416
Here the class. It seems, that the compressed image (blob) is not returned.
Please can you help me!!!!!!
import java.sql.*;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.sql.Blob;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import javax.imageio.IIOImage;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
//import java.sql.SQLException;
class OracleConCompressBLOB{
public static void main(String args[]){
try{
//step1 load the driver class
Blob myBlob = null;
Blob myBlobCopy = null;
Class.forName("oracle.jdbc.driver.OracleDriver");
String dbURL = "jdbc:oracle:thin:#(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = xxxx)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = xxxx) ) )";
String strUserID = "xxxx";
String strPassword = "xxxx";
//step2 create the connection object
Connection con=DriverManager.getConnection(dbURL,strUserID,strPassword);
//HOSTNAME:PORT/SERVICENAME
//step3 create the statement object
Statement stmt=con.createStatement();
//step4 execute query
// fuer pbent ResultSet rs=stmt.executeQuery("select PRFO_ID, PRFO_PRAX_ID , PRFO_DATEINAME, PRFO_FOTO from T_PRAFOTO where PRFO_ID = 17");
ResultSet rs=stmt.executeQuery("select PRFO_ID, PRFO_PRAX_ID , PRFO_DATEINAME, PRFO_FOTO from T_PRAFOTO where PRFO_ID = 126 FOR UPDATE");
if (rs.next()) {
myBlob = rs.getBlob(4);
myBlobCopy = myBlob;
System.out.println(rs.getInt(1)+" "+rs.getInt(2)+" "+rs.getString(3)+" Length of retrieved Blob: " + myBlob.length());
System.out.println(" Length of copy Blob: " + myBlobCopy.length());
System.out.println("Call compressJPEG (myBlobCopy) ");
compressJPEG (myBlobCopy) ;
System.out.println("Back from compressJPEG: Length of retrieved Blob: " + myBlobCopy.length());
}
//step5 close the connection object
con.close();
}catch(Exception e){ System.out.println(e);}
}
public static void compressJPEG(Blob blob) throws IOException {
// File imageFile = new File("myimage.jpg");
// File compressedImageFile = new File("myimage_compressed.jpg");
// InputStream is = new FileInputStream(imageFile);
// OutputStream os = new FileOutputStream(compressedImageFile);
System.out.println("now in compressJPEG");
BufferedImage bufferedImage = null;
OutputStream outputStream = null;
float quality = 0.5f;
try {
// create a BufferedImage as the result of decoding the supplied InputStream
// BufferedImage image = ImageIO.read(is);
bufferedImage = ImageIO.read(blob.getBinaryStream());
outputStream = blob.setBinaryStream(0);
// test
// get all image writers for JPG format
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
if (!writers.hasNext())
throw new IllegalStateException("No writers found");
ImageWriter writer = (ImageWriter) writers.next();
ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
// compress to a given quality
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
// appends a complete image stream containing a single image and
//associated stream and image metadata and thumbnails to the output
writer.write(null, new IIOImage(bufferedImage, null, null), param);
// close all streams
// is.close();
// os.close();
// ios.close();
// writer.dispose();
outputStream.flush();
ios.close();
outputStream.close();
writer.dispose();
} catch (IOException e) {
e.printStackTrace();
}
catch (SQLException e) {
e.printStackTrace();
}
catch(IllegalArgumentException e) {
e.printStackTrace();
}
}
}
The javax.imageio.ImageIO class has the methods:
getWriterFormatNames: Returns an array of Strings listing all of the informal format names understood by the current set of registered writers.
getWriterMIMETypes: Returns an array of Strings listing all of the MIME types understood by the current set of registered writers.
Write a small Java program to run those and return the names/type and then load it into the Oracle database and then run it there (do NOT run it in any JVM installed into the operating system as it will almost certainly not be the same version JVM as the database uses and you may find they support different files).
Then you will know exactly what image formats are supported.

Convert base64 format to pdf in java : output damaged file

I am able to create a pdf file but when I try to open the output pdf file I am getting error : "the file is damaged"
Here is my code please help me.
String encodedBytes= "QmFzZTY0IGVuY29kaW5nIHNjaGVtZXMgYXJlIHVzZWQgd2hlbiBiaW5hcnkgZGF0YSBuZWVkcyB0byBiZSBzdG9yZWQgb3IgdHJhbnNmZXJyZWQgYXMgdGV4dHVhbCBkYXRh";
BASE64Decoder decoder = new BASE64Decoder();
byte[] decodedBytes = decoder.decodeBuffer(encodedBytes);
File file = new File("C:/Users/istest/Documents/test.pdf");
FileOutputStream fos = new FileOutputStream(file);
fos.write(decodedBytes);
Your string is not a valid PDF file.
A pdf file should start its proper Magic number (please refer to the Format indicators section of this link)
PDF files start with "%PDF" (hex 25 50 44 46).
or in Base64 : JVBERi
if you try your code with a valid PDF encoded string like this one, it might work.
But because you did not provided the code of your BASE64Decoder class, it is hard to be sure that it will work.
For that reason, here is a simple implementation of the java.util.Base64 package (Warning do not copy/past this example and do not try it before changing the given base64 string here with the correct one as supplied in the previous link...as noted in the bellow comment, in order to be short the correct string was replaced by a corrupted one)
import java.io.File;
import java.io.FileOutputStream;
import java.util.Base64;
class Base64DecodePdf {
public static void main(String[] args) {
File file = new File("./test.pdf");
try ( FileOutputStream fos = new FileOutputStream(file); ) {
// To be short I use a corrupted PDF string, so make sure to use a valid one if you want to preview the PDF file
String b64 = "JVBERi0xLjUKJYCBgoMKMSAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvRmlyc3QgMTQxL04gMjAvTGVuZ3==";
byte[] decoder = Base64.getDecoder().decode(b64);
fos.write(decoder);
System.out.println("PDF File Saved");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Credit : source.

Decode base64 PDF and write to file in JMeter

I am trying to decode a pdf from a response and write it to a file.
The file gets created and appears to be the correct file size, but when I go to open it, I get an error that says, "There was an error opening this document. The file is damaged and could not be repaired."
I am using the code from this post to decode and create the file.
I set the base64 encoded file returned from the API as the variable vars.get("documentText")
Here is how my BeanShell PostProcessor code looks:
import org.apache.commons.io.FileUtils;
import org.apache.commons.codec.binary.Base64;
String Createresponse= vars.get("documentText");
vars.put("response",new String(Base64.decodeBase64(Createresponse.getBytes("UTF-8"))));
Output = vars.get("response");
f = new FileOutputStream("C:\\Users\\user\\Desktop\\Test.pdf");
p = new PrintStream(f);
this.interpreter.setOut(p);
print(Output);
f.close();
Am I doing something incorrectly?
I have also done the following, but get the same result:
byte[] data = Base64.decodeBase64(vars.get("documentText"));
FileOutputStream out = new FileOutputStream("C:\\Users\\user\\Desktop\\Test.pdf");
out.write(data);
out.close();
EDIT:
The entire PDF from the Response looks like the following: (these are just the first 5 lines (of approx. 7,548 lines), but they are all similar):
JVBERi0xLjQKMSAwIG9iago8PAovVGl0bGUgKP7/KQovQ3JlYXRvciAo/v8pCi9Qcm9kdWNlciAo
/v8AUQB0ACAANQAuADUALgAxKQovQ3JlYXRpb25EYXRlIChEOjIwMTcwMzI3MTgwNTEzKQo+Pgpl
bmRvYmoKMiAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMyAwIFIKPj4KZW5kb2JqCjQg
MCBvYmoKPDwKL1R5cGUgL0V4dEdTdGF0ZQovU0EgdHJ1ZQovU00gMC4wMgovY2EgMS4wCi9DQSAx
LjAKL0FJUyBmYWxzZQovU01hc2sgL05vbmU+PgplbmRvYmoKNSAwIG9iagpbL1BhdHRlcm4gL0Rl
I'm assuming this is what is causing an issue? Is there a way to convert the response to a single String that can be decoded?
EDIT 2:
So the 
 in the response is definitely my problem. I looked up the hex code character and it translates to a carriage return. If I manually copy the Response from within JMeter, paste it into Notepad++, remove 
 and then decode it manually, the PDF opens as it should.
I tried modifying my BeanShell script to remove the carriage return and then decode it, but it still isn't fully functional. The PDF now opens, however, it is just blank white pages. Here is my updated code:
String Createresponse= vars.get("documentText");
String b64 = Createresponse.replace("
","");
vars.put("response",new String(Base64.decodeBase64(b64)));
Output = vars.get("response");
f = new FileOutputStream("C:\\Users\\user\\Desktop\\Test.pdf");
p = new PrintStream(f);
this.interpreter.setOut(p);
print(Output);
f.close();
This works for me. You input data is wrong.
package com.test;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Base64;
import org.junit.Test;
public class TestBase64 {
String data =
"JVBERi0xLjQKMSAwIG9iago8PAovVGl0bGUgKP7/KQovQ3JlYXRvciAo/v8pCi9Qcm9kdWNlciAo/v8AUQB0ACAANQAuADUALgAxKQovQ3JlYXRpb25EYXRlIChEOjIwMTcwMzI3MTgwNTEzKQo+Pgpl";
#Test
public void decodeBase64()
{
byte[] localData = Base64.getDecoder().decode(data);
try (FileOutputStream out = new FileOutputStream("/testout64.dat"))
{
out.write(localData);
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
This results in
%PDF-1.4
1 0 obj
<<
/Title (þÿ)
/Creator (þÿ)
/Producer (þÿ Q t 5 . 5 . 1)
/CreationDate (D:20170327180513)
>>
e
and seems to be valid PDF.
What is the &_#_x_d_;_ part? Seems to be some custom format characters.
I basically had the answer to my question, the problem was with the base64 encoded Response I was trying to decode was multi-line and included carriage return hex code.
My solution to this was to remove the carriage return hex code from the response and condense it to a single string of base64 encoded text and then write the file out.
import org.apache.commons.io.FileUtils;
import org.apache.commons.codec.binary.Base64;
String response = vars.get("documentText");
String encodedFile = response.replace("
","").replaceAll("[\n]+","");
// Decode the response
vars.put("decodedFile",new String(Base64.decodeBase64(encodedFile)));
// Write out the decoded file
Output = vars.get("decodedFile");
file = new FileOutputStream("C:\\Users\\user\\Desktop\\decodedFile.pdf");
p = new PrintStream(file);
this.interpreter.setOut(p);
print(Output);
p.flush();
file.close();

convert image to base64 with java

I need to convert a image object to a base64 object so I can load it into the tag on my client side.
However I can't seem to figure out how to pull this off. Is there anyone who has a piece of code for this that I could use easily?
This is what I use to turn the external image link into a image object
Image image = null;
URL url = new URL(request.getParameter("hdn_path"));
image = ImageIO.read(url);
not sure if I'm going about this the correct way.
Using Apache IOUtils and Base64:
byte[] imageBytes = IOUtils.toByteArray(new URL("...")));
String base64 = Base64.getEncoder().encodeToString(imageBytes);
write using ImageIO.write().
ByteArrayOutputStream wraps the byte array so it can be used as an output stream.
convert the byte array to a a base64 string using DatatypeConverter, in core Java since 6, no extra libraries required
Example
ByteArrayOutputStream output = new ByteArrayOutputStream();
ImageIO.write(image, "png", output);
DatatypeConverter.printBase64Binary(output.toByteArray());
Accepted answer reads the file from URL, if any one looking for image to Base64 encoding by reading the image from file system, below snippet can be used.
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Base64;
import org.apache.commons.io.IOUtils;
public String img2Text(){
String base64="";
try{
InputStream iSteamReader = new FileInputStream("featured-700x467.png");
byte[] imageBytes = IOUtils.toByteArray(iSteamReader);
base64 = Base64.getEncoder().encodeToString(imageBytes);
System.out.println(base64);
}catch(Exception e){
e.printStackTrace();
}
return "data:image/png;base64,"+base64;
}
Returned base64 text can be used in HTML pages like below example
<!DOCTYPE html>
<html>
<body>
<img src="data:image/png;base64,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
" alt="Smiley face" width="42" height="42">
</body>
</html>

Categories