HtmlUnit use WebClient to download an image as base64 encoded DATA Uri - java

I want to use an existing instance of WebClient to download an image. The reason for this is because I want the cookies to be passed with the request.
How can I download an image using an existing instance of WebClient?
Also, how can I base64 encode the image to be able to view it using data:image/jpeg;base64,...
Current code:
WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6);
UnexpectedPage imagePage = client.getPage("http://...");
String imageString = imagePage.getWebResponse().getContentAsString();
BASE64Encoder encoder = new BASE64Encoder();
String base64data = encoder.encode(imageString.getBytes());
So now I have base64 data of the image, but I still can't view the image using data:image/jpeg;base64,....

A couple of things to consider:
The BASE64Encoder() generates a string that has a line break every 77 chars. Take that out using .replaceAll("\r?\n","").
For that method also, it is better to retrieve the web page InputStream rather than the string. Also, to convert that to a byte array, I used a utility method (source and other options can be found here).
Working source code:
public static void main (String args[]) throws IOException {
WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6);
UnexpectedPage imagePage = client.getPage("http://i.stack.imgur.com/9DdHc.jpg");
BASE64Encoder encoder = new BASE64Encoder();
String base64data = encoder.encode(inputStreamToByteArray(imagePage.getWebResponse().getContentAsStream()));
System.out.println("<img src=\"data:image/png;base64,"+base64data.replaceAll("\r?\n","")+"\" />");
}
private static byte[] inputStreamToByteArray(InputStream is) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
return buffer.toByteArray();
}
Source image:
Output base64 image here.

Related

Java MimeBodyPart to byte[]

I am using Java 11. I am reading emails and retrieving their attachments using javax.mail and would like to save the attachments byte array.
So I need to convert a javax.mail.internet.MimeBodyPart (the attachment) to a byte[].
code so far:
private void savePDF(MimeBodyPart attachment, String invoiceNumber) {
byte[] data = attachment.get....
}
More info:
When I try open the PDF, I do the following:
InputStream is = response.getStream();
byte[] bytes = IOUtils.toByteArray(is);
OutputStream output = response.getOutputStream();
fos = new BufferedOutputStream(output);
fos.write(bytes);
This works perfectly when I get the bytes from a 'MultipartFile':
byte[] bytes = multipartFile.getBytes();
However, if I try use the byes from a MimeBodyPart (email attachment), it fails:
byte[] data = attachment.getInputStream().readAllBytes();
More info:
I have also tried, but I get the same error:
BASE64DecoderStream content = (BASE64DecoderStream) attachment.getContent();
byte[] bytes = content.readAllBytes();
bytes = Base64.decodeBase64(bytes);

Java Apache PDFBox - Encryption not deterministic

I have the following code.
public byte[] encryptPdf(byte[] pdf, String password) throws IOException {
ByteArrayOutputStream baos;
try (PDDocument pdDocument = PDDocument.load(pdf)) {
AccessPermission accessPermission = new AccessPermission();
StandardProtectionPolicy protectionPolicy = new
StandardProtectionPolicy(null, password, accessPermission);
protectionPolicy.setEncryptionKeyLength(128);
protectionPolicy.setPermissions(accessPermission);
pdDocument.protect(protectionPolicy);
baos = new ByteArrayOutputStream();
pdDocument.save(baos);
}
return baos.toByteArray();
}
#Test
public void shouldEncryptedPDFEquals() {
byte[] pdf = IOUtils.toByteArray(getClass().getClassLoader().getResourceAsStream("sample.pdf"));
byte[] firstEncryption = encryptPdf(pdf, "token");
byte[] secondEncryption = encryptPdf(pdf, "token");
assertThat(firstEncryption.length, is(secondEncryption.length));
}
Inside a test i will check encrypted documents if there are equals.
The Problem is, that the generates byte array is not deterministic.
If i call the method multiple times, the array length are not ever equals. The assert failed. But not for all types of pdf files.
Is there a bug inside the Apache PDFBox library?

PNG image from java server to android

I'm trying to send multiple PNG:s to an adroid-phone.
(Every image is sent in a separate JSON-object together with multiple other objects that is associated with the image.)
I'm sending the images as byte-arrays and my phone is receiving them.
The problem starts when I try to decode with BitmapFactory.decodeByteArray which returns null.
How should I encode on the server-side and decode on the android-side?
First attempt on server-side:
File imgPath = new File(path);
BufferedImage bufferedImage = ImageIO.read(imgPath);
WritableRaster raster = bufferedImage.getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
byte[] bytes = data.getData();
Second attempt on server-side:
byte[] bytes = null;
File file = new File(path);
bytes = Files.readAllBytes(file.toPath());
Android-side:
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
mImageView.setImageBitmap(bitmap);
Sending JSON from server:
public class Response {
List<Person> mPeople;
..other objects...
}
public class Person {
String name;
String image; //base68string
}
public ServerThread {
Response resp = create objects to send;
String str = new Gson().toJson(resp);
OutputStreamWriter.write(str);
}
Receiving JSON on Android-side:
Response resp = gson.fromJson(str, Response.class);
List<Person> = resp.getPersons();
//Person-class on the android side is Parcable
So I tried this approach but it still doesn't work:
// Server-side
import java.util.Base64;
import java.util.Base64.Encoder;
File file = new File(path);
byte[] bytes = Files.readAllBytes(file.toPath());
Encoder e = Base64.getEncoder();
String base64String = e.encodeToString(bytes);
//Android-side
byte[] bytes = Base64.decode(base64String, Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
mImageView.setImageBitmap(bitmap);
I suggest you to try Picasso or Glide to load image into imageview directly from the URL. You don't have to manage this all stuff manually.
I was doing that stuff but after using one of this library it removes lots of work.
Just try this.

To display a Base64 image in AngularJS

I have inserted a Base64 image to a database using this Java code:
FileInputStream mFileInputStream = new FileInputStream("C:\\basicsworkspace\\base64upload\\src\\main\\resources\\basic.png");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int bytesRead = 0;
while ((bytesRead = mFileInputStream.read(b)) != -1) {
bos.write(b, 0, bytesRead);
}
byte[] ba = bos.toByteArray();
//byte[] encoded = Base64.getEncoder().encode(ba); // Util
byte[] encoded = Base64.encodeBase64(ba); // Apache
connection = DriverManager.getConnection(connectionString);
String insertSql = "INSERT INTO test (image) VALUES (?)" ;
prepsInsertProduct.setBytes(encoded);
System.out.println(insertSql);
prepsInsertProduct = connection.prepareStatement(insertSql);
System.out.println(prepsInsertProduct.execute());
But if I try to display the image in AngularJS using it, it is not displaying the image. In SQL Server I have saved my image as varbinary(max) and in AngularJS code,
config(function ($compileProvider) {
console.log($compileProvider.imgSrcSanitizationWhitelist());
})
<img src="choice:image/png;base64,{{choice.Icon}}">
But I am getting only bytes with a message like this:
unsafe:choice:image/png;base64,6956424F5277304B47676F414141414E535568455567…
Where am I going wrong? The image is in PNG format.
In POJO I made changes for byte[] and it worked. I have datatype with String and modified to byte[] but Base64 images didn't displayed but t is displaying only byte array images.
Try in your controller:
$scope.choice.Icon = 'data:image/jpeg;base64,' + yourImageData;
And in your HTML content:
<img ng-src="{{choice.Icon}}">

Save Image Byte Array to .net webservice and retrieve it

I have a .net ASMX webservice that I'm consuming using the ksoap2 library. In the service, I first save the user image and later retrieve it. However, once I retrieve it, the byte array is intact, but the BitmapFactory is unable to decode it and returns a null.
To convert to byte array:
Bitmap viewBitmap = Bitmap.createBitmap(imageView.getWidth(),
imageView.getHeight(), Bitmap.Config.ARGB_8888);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
viewBitmap.compress(CompressFormat.PNG, 0 /* ignored for PNG */, bos);
byte[] bitmapdata = bos.toByteArray();
The webservice accepts the bytearray in the byte[] format.
To convert the array into bitmap:
byte[] blob= info.get(Main.KEY_THUMB_BYTES).getBytes();
Bitmap bmp=BitmapFactory.decodeByteArray(blob,0,blob.length); // Return null :(
imageView.setImageBitmap(bmp);
From partial-analysis, it appears that the byte array does not change. Then why does decoding return null? Is there a better to save an image and pass it through a webservice? I didn't analyze the whole byte array, so I'm guessing it might've changed a bit.
Any thoughts? Many thanks!
UPDATE:
I just tried converting the byte[] to string using:
Base64.encodeToString( bos.toByteArray(), Base64.DEFAULT);
And decode using:
byte[] blob= Base64.decode(info.get(Main.KEY_THUMB_BYTES));
Now all i get is a White picture. I'm not sure what's wrong here. Please help.
UPDATE:
I'm storing this image inside of a database, in a column of type varchar(max). Should I be storing this byte array string inside a different sql data type? I'm not too experienced with SQL, so I used varchar because it did not convert text to unicode, which I thought might be good for thie byte array.
Thanks!
convert your byte arrays to Base64 that is a string and easy to transfer:
public static String bitmapToBase64(Bitmap bitmap) {
byte[] bitmapdata = bitmapToByteArray(bitmap);
return Base64.encodeBytes(bitmapdata);
}
public static byte[] bitmapToByteArray(Bitmap bitmap) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0 /* ignored for PNG */, bos);
byte[] bitmapdata = bos.toByteArray();
return bitmapdata;
}
and
public static Bitmap base64ToBitmap(String strBase64) throws IOException {
byte[] bitmapdata = Base64.decode(strBase64);
Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapdata, 0,
bitmapdata.length);
return bitmap;
}
also you can do it not only on image files but also on every file types:
public static String fileToBase64(String path) throws IOException {
byte[] bytes = fileToByteArray(path);
return Base64.encodeBytes(bytes);
}
public static byte[] fileToByteArray(String path) throws IOException {
File imagefile = new File(path);
byte[] data = new byte[(int) imagefile.length()];
FileInputStream fis = new FileInputStream(imagefile);
fis.read(data);
fis.close();
return data;
}
public static void base64ToFile(String path, String strBase64)
throws IOException {
byte[] bytes = Base64.decode(strBase64);
byteArrayTofile(path, bytes);
}
public static void byteArrayTofile(String path, byte[] bytes)
throws IOException {
File imagefile = new File(path);
File dir = new File(imagefile.getParent());
if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(imagefile);
fos.write(bytes);
fos.close();
}

Categories

Resources