Base91 string corruption in mysql database - java

I'm using Base91 to store an image as a String in a mysql database. When I retrieve the string to convert it back to an image, the string seems to have been corrupted by the database.
I'm sure it's being corrupted in the database because I did an isolated test on a single device of taking a picture, converting it to a Base91 byte[], converting the byte[] to a string (using Latin1), converting the string back to byte[], then to an image, and it worked. When I try that with a server in the middle, the images end up broken.
I've tried changing the collation on the specific column on the database from utf8 to ascii to latin1, no luck.
Code:
Encoding Picture:
File file1 = new File(path);
FileInputStream in = new FileInputStream(file1);
byte[] imagesBytes = new byte[(int) file1.length()];
in.read(imagesBytes, 0, (int) file1.length());
_picture = new String(Base91.encode(imagesBytes), Base91.CHARSET);
//appointment.addPicture(new String(Base91.encode(imagesBytes), Base91.CHARSET));
Storing encoded image:
JsonObject jsonx = new JsonObject();
jsonx.addProperty("picture", request.getParameter("picture"));
db.insert("AppointmentPicture",
"(AppointmentID, picture)values(?,?)",
new Object[]{appointment.getDbID(), jsonx.toString()},
false);
Retrieving the image:
ResultSet rSet = db.query("AppointmentPicture", new String[]{"picture"}, "AppointmentID = ?", new Object[]{appointmentID});
System.out.println("pictures grabbed");
JsonObject json = new JsonObject();
int counter = 0;
while (rSet.next()) {
counter++;
json.addProperty(String.valueOf(counter), rSet.getString("picture"));
}
json.addProperty("count", String.valueOf(counter));
response.getWriter().write(json.toString());
System.out.println("pictures returned");
Decoding Image:
String serverResponse = in.readLine();
JSONObject json = new JSONObject(serverResponse);
int count = Integer.parseInt(json.getString("count"));
for(int i = 0; i < count; i++){
JSONObject j = new JSONObject(json.getString(String.valueOf(i + 1)));
byte[] picBytes = j.getString("picture").getBytes(Base91.CHARSET);
File file = new File(imageDirectory, String.valueOf(System.currentTimeMillis()) + ".jpeg");
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
out.write(picBytes, 0, picBytes.length);
}

Related

Convert blob to string to to create a json object and then change the string back to blob

My requirement is to convert the blob in a database field to string to create a json object. I have achieved that.
Now, I need to convert this string back to blob. I wrote the below code. But, it does not work. In my instance, I have the word document stored as blob. I converted it to string but when I converted the string to blob, the document does not open properly.
Please let me know a way to convert the string back to blob.
DocumentTemplateKey documentTemplateKey = new DocumentTemplateKey();
documentTemplateKey.documentTemplateID = "XX";
DocumentTemplateDtls documentTemplateDtls = DocumentTemplateFactory.newInstance().read(documentTemplateKey);
byte[] blobAsBytes = documentTemplateDtls.contents.copyBytes();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(blobAsBytes, 0, blobAsBytes.length);
String pdfBase64String =
org.apache.commons.codec.binary.StringUtils.newStringUtf8(org.apache.
commons.codec.binary.Base64.encodeBase64(bos.toByteArray()));
OutputStreamWriter out = new OutputStreamWriter(System.out);
JsonWriter writer = new JsonWriter(out);
//set indentation for pretty print
writer.setIndent("\t");
//start writing
writer.beginObject(); //{
writer.name("blob").value(pdfBase64String);
byte[] stringAsBytes = org.apache.commons.codec.binary.StringUtils.getBytesUtf8(pdfBase64String);
Blob blob = new Blob(stringAsBytes);
documentTemplateDtls.contents = blob;
documentTemplateDtls.documentTemplateID = "XX12";
documentTemplateDtls.name = "XX12";
DocumentTemplateFactory.newInstance().insert(documentTemplateDtls);
writer.endObject();
writer.flush();
//close writer
writer.close();
Here's your problem:
byte[] stringAsBytes = org.apache.commons.codec.binary.StringUtils.getBytesUtf8(pdfBase64String);
You're getting the bytes of your base64 string, but you ought to be putting it through a base64 decoder.

Creating corrupted PDF from bytearray

I was trying to generate PDf from byte array in Java which was returned through webservice, But the PDF cannot be opened. It shows its corrupted, I have attached my code. Anyone pls help about where i got wrong?
JSONObject o = new JSONObject(outjson);
JSONObject jsonob = o.optJSONObject("PDF details");
byte[] pdfbyte=jsonob.optString("pdf bytearray").toString().getBytes();
String str1 = new String(pdfbyte);
File someFile = new File("C:/Users/acer/Desktop/test1.pdf");
FileOutputStream fos = new FileOutputStream(someFile);
byte[] byteData = str1.getBytes();
byte[] byteData1 = test.getBytes();
fos.write(pdfbyte);
fos.flush();
fos.close();
Following is my JSON from webservice:
{"PDF details": {
"id":"121",
"pdf bytearray":"[B#62a58cd"
}
}
Following is my webservice code which outputs bytearray in json:
public Response getPdf( )
{
String flag=null;
File file = new File("C:/Users/acer/Desktop/Report.pdf");
FileInputStream fileInputStream;
byte[] data = null;
byte[] finalData = null;
ByteArrayOutputStream byteArrayOutputStream = null;
fileInputStream = new FileInputStream(file);
data = new byte[(int)file.length()];
finalData = new byte[(int)file.length()];
byteArrayOutputStream = new ByteArrayOutputStream();
fileInputStream.read(data);
byteArrayOutputStream.write(data);
finalData = byteArrayOutputStream.toByteArray();
fileInputStream.close();
System.out.println(finalData);
JSONObject jsonObject = new JSONObject();
JSONObject mainjsonObject = new JSONObject();
jsonObject.put("id","121");
jsonObject.put("pdf bytearray",finalData);
mainjsonObject.put("PDF details",jsonObject);
flag = "" + mainjsonObject;
return Response.status(200).entity(flag).build();
}
i got it right with following chnge in my webservice:
public Response getPdf( )
{
String flag=null;
File file = new File("C:/Users/acer/Desktop/Report.pdf");
FileInputStream fileInputStreamReader = new FileInputStream(file);
byte[] bytes = new byte[(int)file.length()];
fileInputStreamReader.read(bytes);
String encodedBase64 = new String(Base64.encodeBase64(bytes));
JSONObject jsonObject = new JSONObject();
JSONObject mainjsonObject = new JSONObject();
jsonObject.put("id","121");
jsonObject.put("pdf bytearray",encodedBase64);
mainjsonObject.put("PDF details",jsonObject);
flag = "" + mainjsonObject;
return Response.status(200).entity(flag).build();
}
my Client:
String encodedBase64=jsonob.optString("pdf bytearray");
byte[] decodedBytes = Base64.decodeBase64(encodedBase64);
System.out.println("decbyte "+decodedBytes);
File someFile = new File("C:/Users/acer/Desktop/test.pdf");
OutputStream fos = new FileOutputStream(someFile);
fos.write(decodedBytes);
fos.flush();
fos.close();

How to put byte stream image data into JSON object?

I want to put multiple images in JSON object using byte stream format, i wrote the following code.
FileInputStream fin = new FileInputStream(pathToImages+"//"+"01.jpg");
BufferedInputStream bin = new BufferedInputStream(fin);
BufferedOutputStream bout = new BufferedOutputStream(out);
int ch =0; ;
sun.misc.BASE64Encoder encoder= new sun.misc.BASE64Encoder();
byte[] contents = new byte[5000000];
int bytesRead = 0;
String strFileContents;
while ((bytesRead = bin.read(contents)) != -1) {
bout.write(encoder.encode(contents).getBytes());
}
JsonObject myObj = new JsonObject();
I want to put encoded byte stream in myObj,but dont know how to do it.
Thanks
JSONObject myObj = new JSONObject();
myObj.put("1",encoder.encode(contents).getBytes());
I think this will work.
Assuming you are using Java 8, and the javax.json package:
Path path = Paths.get(pathToImages, "01.jpg");
ByteArrayOutputStream bytes = new ByteArrayOutputStream(
(int) (Files.size(path) * 4 / 3 + 4));
try (OutputStream base64Stream = Base64.getEncoder().wrap(bytes)) {
Files.copy(path, base64Stream);
}
String base64 = bytes.toString("US-ASCII");
JsonObjectBuilder builder = Json.createObjectBuilder();
builder.add("data", base64);
JsonObject myObj = builder.build();

Saving multi-layered TIFF images without losing layer information in Java

I'm trying to save tiff images uploaded via browser using Spring and JAI ImageIO. I can save the image using the code below but the problem is that the saved image doesn't have the layers(the ones that tiff images consist of) which it has before uploading.
Are there any other parameters to ensure that the saved image also has the layers?
private void saveTiffImage(byte[] bytes, String uuid) throws Exception {
SeekableStream stream = new ByteArraySeekableStream(bytes);
String[] names = ImageCodec.getDecoderNames(stream);
ImageDecoder dec =
ImageCodec.createImageDecoder(names[0], stream, null);
RenderedImage im = dec.decodeAsRenderedImage();
String fileName = uuid + ".tif";
com.sun.media.jai.codec.TIFFEncodeParam params = new com.sun.media.jai.codec.TIFFEncodeParam();
params.setCompression(com.sun.media.jai.codec.TIFFEncodeParam.COMPRESSION_PACKBITS);
FileOutputStream os = new FileOutputStream(IMG_LOCATION + fileName);
javax.media.jai.JAI.create("filestore", im, IMG_LOCATION + fileName, "TIFF", params);
os.flush();
os.close();
}
I've found the solution using the answer here : How to combine two or many tiff image files in to one multipage tiff image in JAVA.
private Object[] saveTiffImage(byte[] bytes, String uuid) throws Exception {
SeekableStream stream = new ByteArraySeekableStream(bytes);
String[] names = ImageCodec.getDecoderNames(stream);
ImageDecoder dec =
ImageCodec.createImageDecoder(names[0], stream, null);
// Here we get the other pages.
Vector vector = new Vector();
int pageCount = dec.getNumPages();
for (int i = 1; i < pageCount; i++) {
RenderedImage im = dec.decodeAsRenderedImage(i);
vector.add(im);
}
String fileName = uuid + ".tif";
com.sun.media.jai.codec.TIFFEncodeParam params = new com.sun.media.jai.codec.TIFFEncodeParam();
params.setCompression(com.sun.media.jai.codec.TIFFEncodeParam.COMPRESSION_PACKBITS);
// Then set here
params.setExtraImages(vector.iterator());
// This is the first page
RenderedImage im = dec.decodeAsRenderedImage(0);
FileOutputStream os = new FileOutputStream(IMG_LOCATION + fileName);
javax.media.jai.JAI.create("filestore", im, IMG_LOCATION + fileName, "TIFF", params);
os.flush();
os.close();
}

inserting image to sqlite

I'm creating application using sqlite database and netbeans .I have a problem when I save an image to data base.
I have an image field in database which data type is BLOB and i'm inserting a byte array . i know it doesn't match.but when i save it holds value like this "[B#2c8f544b" but actual values should be like this "BLOB (Size: 1850)". if there is some value like that then only i can retrieve the image. I really can't figure out how to do this.if you have any reference please let me know.
my idea is before save to database convert byte array to BLOB type.but I couldn't find any code.
String fname = p.fname;
String lname = p.lname;
byte[] image = p.image_det;
String mob = p.mobile;
String wor = p.work;
String hom = p.home;
String fax = p.fax;
int pID ;
ResultSet rst = stmt.executeQuery("SELECT MAX(pID) FROM person");
pID = Integer.parseInt(rst.getString(1))+1;
Statement stmt1 = con.createStatement();
stmt1.executeUpdate("INSERT INTO person(pID,F_name,L_name,image) VALUES ("+pID+" ,'"+fname+"','"+lname+"','"+image+"' ) ");
//-------------------------getting image path and get image data to array called image_details
File f;
String ipath = f.getAbsolutePath(); // getting image path
byte[] image_detail = null;
try
{
File image = new File(ipath);
FileInputStream fis = new FileInputStream(image);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
for(int readNum;(readNum = fis.read(buf))!= -1;)
{
baos.write(buf, 0,readNum);
}
image_detail = baos.toByteArray();
per.setImage_det(image_detail); // set image data for person class

Categories

Resources