Image to byte array in Codename One - java

I need to convert an image into a byte array in my Codename One app.
It will be used to create a base64 representation of the image to be used in a BrowserComponent.
I tried this:
byte[] bytes=new byte[10];
String base64IconString="data:image/png;base64,";
try(InputStream is = getClass().getResourceAsStream("/icon.png");) {
bytes=new byte[is.available()];
// the instruction above is wrong. it will fail
// use Util.readInputStream(InputStream) in Codename One instead
// see comments
Util.readAll(is, bytes);
base64IconString+=Base64.encode(bytes);
} catch(IOException err) {
Log.e(err);
}
I put the result into this:
browserComponent.setPage("<HTML><BODY>" + "<img src='"+base64IconString+"' />" + "</BODY></HTML>");
It works, but I need to create the base64 string from a Image that has no path or file name because it is from a special class MyImageFromSVGSubset.
This tool is used to generate that class: https://www.codenameone.com/blog/flamingo-svg-transcoder.html
Note: the Image class in CodenameOne has also the int[] getRGB() method.
How to achieve my goal?

You can use ImageIO which is designed exactly for that: converting an Image to bytes. However, there's a slightly simpler hack. EncodedImage supports this out of the box so:
EncodedImage em = EncodedImage.createFromImage(otherImage, jpegOrPNG);
byte[] data = em.getImageData();
Also see BrowserComponent.createDataURI(byte[], mime).

Related

Convert base64 string to image at server side in java

I have base64 String which I want to convert back to image irrespective of image format at server side. I tried it by using following code, image is getting created but when I am trying to preview it, showing error could not load image.
public void convertStringToImage(String base64) {
try {
byte[] imageByteArray = decodeImage(base64);
FileOutputStream imageOutFile = new FileOutputStream("./src/main/resources/demo.jpg");
imageOutFile.write(imageByteArray);
imageOutFile.close();
} catch (Exception e) {
logger.log(Level.SEVERE, "ImageStoreManager::convertStringToImage()" + e);
}
}
public static byte[] decodeImage(String imageDataString) {
return Base64.decodeBase64(imageDataString);
}
what should I do so that my image will look properly?
Your code looks fine. I can suggest however some more debugging steps for you.
Encode your file manually using, for example, this webpage
Compare if String base64 contains exact same content like you've got seen on the page. // if something wrong here, your request is corrupted, maybe some encoding issues on the frontend side?
See file content created under ./src/main/resources/demo.jpg and compare content (size, binary comparison) // if something wrong here you will know that actually save operation is broken
Remarks:
Did you try to do .flush() before close?
Your code in current form might cause resource leakage, have a look at try-with-resources
Try this:
public static byte[] decodeImage(String imageDataString) {
return org.apache.commons.codec.binary.Base64.decodeBase64(imageDataString.getBytes());
}

Same Image, but different base64

I used the following function to create a base64 encoded string of my Gravatar image (https://www.gravatar.com/avatar/cd5415f97afbe0177ba35ae31fbfd0db):
final BASE64Encoder encoder = new BASE64Encoder();
String encoded = encoder.encode(inputStreamToByteArray(is));
encoded = encoded.replaceAll("\r?\n", "");
return encoded;
I ran the method a couple of days ago and got the following base64 encoded string:
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
Just today I executed the method again, using the same image. But instead of retrieving the same encoded string, I received:
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
As you may notice, the first couple of characters are the same, but if you look at the end of the strings, you notice directly that they are completely different. Why is that? The image is still my Gravatar image (e.g., using http://codebeautify.org/base64-to-image-converter shows the same image for both strings).
Thanks for any hint, explanation! Is there anything wrong with my implementation? Is some of the implementation time or location dependent? How can I get the same base64 string for the same image?
PS: inputStreamToByteArray is implemented as follows:
public static byte[] inputStreamToByteArray(final InputStream is) {
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
final byte[] data = new byte[16384];
try {
int nRead;
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
} catch (final IOException e) {
return null;
} finally {
try {
buffer.close();
} catch (final IOException e) {
// ignore
}
}
return buffer.toByteArray();
}
Converting both images back to .jpg, and using http://regex.info/exif.cgi, the following header comments appear:
One:
CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 90
Other:
CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90
(can't remember which order I converted the images in, but there is a version change either way)
As you can see, they have upgraded the JPEG compressor (or spec?) to a newer version, resulting in a different JPEG encoding, or at least difference in the comments.
So to answer your question, there does not seem to be an issue with your base64 converter, but just that the two images actually are different

Deserialization of an image from string with unknown encoding

I have a set of serialized images which I want to deserialize. The data looks like the following:
GIF89ax\000\364\001\367\000\000\000\000\000\001\001\001\002\002\002\003\003\003\004\004\004\005\005\005\006\006\006\a\a\a\b\b\b\t\t\t\n\n\n\v\v\v\f\f\f\r\r\ ...
Due to data privacy I cann't post an full image. I have trouble to find out what kind of encoding this is. Now I'm struggeling to find a away to convert this to an BufferedImage in Java.
It turned out that the images were serialzed with Google-Protocoll Buffer TextFormat. So the code which converted the code correctly is
import com.google.protobuf.ByteString;
import com.google.protobuf.TextFormat;
String imgStr = "GIF89ax\000\364\001\367\000\000\000\000\000\001\001\001\002\002\002\003\003\003\004\004\004\005\005\005\006\006\006\a\a\a\b\b\b\t\t\t\n\n\n\v\v\v\f\f\f\r\r\ ..."; // must an full image string
ByteString unescapeBytes = TextFormat.unescapeBytes(imgStr);
byte[] bytes = new byte[unescapeBytes.size()];
unescapeBytes.copyTo(bytes, 0);
final BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream("result.gif"));
bw.write(bytes);
bw.close();
Thats it.

Java Apache FileUtils readFileToString and writeStringToFile problems

I need to parse a java file (actually a .pdf) to an String and go back to a file. Between those process I'll apply some patches to the given string, but this is not important in this case.
I've developed the following JUnit test case:
String f1String=FileUtils.readFileToString(f1);
File temp=File.createTempFile("deleteme", "deleteme");
FileUtils.writeStringToFile(temp, f1String);
assertTrue(FileUtils.contentEquals(f1, temp));
This test converts a file to a string and writtes it back. However the test is failing.
I think it may be because of the encodings, but in FileUtils there is no much detailed info about this.
Anyone can help?
Thanks!
Added for further undestanding:
Why I need this?
I have very large pdfs in one machine, that are replicated in another one. The first one is in charge of creating those pdfs. Due to the low connectivity of the second machine and the big size of pdfs, I don't want to synch the whole pdfs, but only the changes done.
To create patches/apply them, I'm using the google library DiffMatchPatch. This library creates patches between two string. So I need to load a pdf to an string, apply a generated patch, and put it back to a file.
A PDF is not a text file. Decoding (into Java characters) and re-encoding of binary files that are not encoded text is asymmetrical. For example, if the input bytestream is invalid for the current encoding, you can be assured that it won't re-encode correctly. In short - don't do that. Use readFileToByteArray and writeByteArrayToFile instead.
Just a few thoughts:
There might actually some BOM (byte order mark) bytes in one of the files that either gets stripped when reading or added during writing. Is there a difference in the file size (if it is the BOM the difference should be 2 or 3 bytes)?
The line breaks might not match, depending which system the files are created on, i.e. one might have CR LF while the other only has LF or CR. (1 byte difference per line break)
According to the JavaDoc both methods should use the default encoding of the JVM, which should be the same for both operations. However, try and test with an explicitly set encoding (JVM's default encoding would be queried using System.getProperty("file.encoding")).
Ed Staub awnser points why my solution is not working and he suggested using bytes instead of Strings. In my case I need an String, so the final working solution I've found is the following:
#Test
public void testFileRWAsArray() throws IOException{
String f1String="";
byte[] bytes=FileUtils.readFileToByteArray(f1);
for(byte b:bytes){
f1String=f1String+((char)b);
}
File temp=File.createTempFile("deleteme", "deleteme");
byte[] newBytes=new byte[f1String.length()];
for(int i=0; i<f1String.length(); ++i){
char c=f1String.charAt(i);
newBytes[i]= (byte)c;
}
FileUtils.writeByteArrayToFile(temp, newBytes);
assertTrue(FileUtils.contentEquals(f1, temp));
}
By using a cast between byte-char, I have the symmetry on conversion.
Thank you all!
Try this code...
public static String fetchBase64binaryEncodedString(String path) {
File inboundDoc = new File(path);
byte[] pdfData;
try {
pdfData = FileUtils.readFileToByteArray(inboundDoc);
} catch (IOException e) {
throw new RuntimeException(e);
}
byte[] encodedPdfData = Base64.encodeBase64(pdfData);
String attachment = new String(encodedPdfData);
return attachment;
}
//How to decode it
public void testConversionPDFtoBase64() throws IOException
{
String path = "C:/Documents and Settings/kantab/Desktop/GTR_SDR/MSDOC.pdf";
File origFile = new File(path);
String encodedString = CreditOneMLParserUtil.fetchBase64binaryEncodedString(path);
//now decode it
byte[] decodeData = Base64.decodeBase64(encodedString.getBytes());
String decodedString = new String(decodeData);
//or actually give the path to pdf file.
File decodedfile = File.createTempFile("DECODED", ".pdf");
FileUtils.writeByteArrayToFile(decodedfile,decodeData);
Assert.assertTrue(FileUtils.contentEquals(origFile, decodedfile));
// Frame frame = new Frame("PDF Viewer");
// frame.setLayout(new BorderLayout());
}

Java - Image encoding in XML

I thought I would find a solution to this problem relatively easily, but here I am calling upon the help from ye gods to pull me out of this conundrum.
So, I've got an image and I want to store it in an XML document using Java. I have previously achieved this in VisualBasic by saving the image to a stream, converting the stream to an array, and then VB's xml class was able to encode the array as a base64 string. But, after a couple of hours of scouring the net for an equivalent solution in Java, I've come back empty handed. The only success I have had has been by:
import it.sauronsoftware.base64.*;
import java.awt.image.BufferedImage;
import org.w3c.dom.*;
...
BufferedImage img;
Element node;
...
java.io.ByteArrayOutputStream os = new java.io.ByteArrayOutputStream();
ImageIO.write(img, "png", os);
byte[] array = Base64.encode(os.toByteArray());
String ss = arrayToString(array, ",");
node.setTextContent(ss);
...
private static String arrayToString(byte[] a, String separator) {
StringBuffer result = new StringBuffer();
if (a.length > 0) {
result.append(a[0]);
for (int i=1; i<a.length; i++) {
result.append(separator);
result.append(a[i]);
}
}
return result.toString();
}
Which is okay I guess, but reversing the process to get it back to an image when I load the XML file has proved impossible. If anyone has a better way to encode/decode an image in an XML file, please step forward, even if it's just a link to another thread that would be fine.
Cheers in advance,
Hoopla.
I've done something similar (encoding and decoding in Base64) and it worked like a charm. Here's what I think you should do, using the class Base64 from the Apache Commons project:
// ENCODING
BufferedImage img = ImageIO.read(new File("image.png"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(img, "png", baos);
baos.flush();
String encodedImage = Base64.encodeToString(baos.toByteArray());
baos.close(); // should be inside a finally block
node.setTextContent(encodedImage); // store it inside node
// DECODING
String encodedImage = node.getTextContent();
byte[] bytes = Base64.decode(encodedImage);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));
Hope it helps.
Apache Commons has a Base64 class that should be helpful to you:
From there, you can just write out the bytes (they are already in a readable format)
After you get your byte array
byte[] array = Base64.encode(os.toByteArray());
use an encoded String :
String encodedImg = new String( array, "utf-8");
Then you can do fun things in your xml like
<binImg string-encoding="utf-8" bin-encoding="base64" img-type="png"><![CDATA[ encodedIImg here ]]></binImg>
With Java 6, you can use DatatypeConverter to convert a byte array to a Base64 string:
byte[] imageData = ...
String base64String = DatatypeConverter.printBase64Binary(imageData);
And to convert it back:
String base64String = ...
byte[] imageData = DatatypeConverter.parseBase64Binary(base64String);
Your arrayToString() method is rather bizarre (what's the point of that separator?). Why not simply say
String s = new String(array, "US-ASCII");
The reverse operation is
byte[] array = s.getBytes("US-ASCII");
Use the ASCII encoding, which should be sufficient when dealing with Base64 encoded data. Also, I'd prefer a Base64 encoder from a reputable source like Apache Commons.
You don't need to invent your own XML data type for this. XML schema defines standard binary data types, such as base64Binary, which is exactly what you are trying to do.
Once you use the standard types, it can be converted into binary automatically by some parsers (like XMLBeans). If your parser doesn't handle it, you can find classes for base64Binary in many places since the datatype is widely used in SOAP, XMLSec etc.
most easy implementation I was able to made is as below, And this is from Server to Server XML transfer containing binary data Base64 is from the Apache Codec library:
- Reading binary data from DB and create XML
Blob blobData = oRs.getBlob("ClassByteCode");
byte[] bData = blobData.getBytes(1, (int)blobData.length());
bData = Base64.encodeBase64(bData);
String strClassByteCode = new String(bData,"US-ASCII");
on requesting server read the tag and save it in DB
byte[] bData = strClassByteCode.getBytes("US-ASCII");
bData = Base64.decodeBase64(bData);
oPrStmt.setBytes( ++nParam, bData );
easy as it can be..
I'm still working on implementing the streaming of the XML as it is generated from the first server where the XML is created and stream it to the response object, this is to take care when the XML with binary data is too large.
Vishesh Sahu
The basic problem is that you cannot have an arbitrary bytestream in an XML document, so you need to encode it somehow. A frequent encoding scheme is BASE64, but any will do as long as the recipient knows about it.
I know that the question was aking how to encode an image via XML, but it is also possible to just stream the bytes via an HTTP GET request instead of using XML and encoding an image. Note that input is a FileInputStream.
Server Code:
File f = new File(uri_string);
FileInputStream input = new FileInputStream(f);
OutputStream output = exchange.getResponseBody();
int c = 0;
while ((c = input.read()) != -1) {
output.write(c); //writes each byte to the exchange.getResponseBody();
}
result = new DownloadFileResult(int_list);
if (input != null) {input.close();}
if (output != null){ output.close();}
Client Code:
InputStream input = connection.getInputStream();
List<Integer> l = new ArrayList<>();
int b = 0;
while((b = input.read()) != -1){
l.add(b);//you can do what you wish with this list of ints ie- write them to a file. see code below.
}
Here is how you would write the Integer list to a file:
FileOutputStream out = new FileOutputStream("path/to/file.png");
for(int i : result_bytes_list){
out.write(i);
}
out.close();
node.setTextContent( base64.encodeAsString( fileBytes ) )
using org.apache.commons.codec.binary.Base64

Categories