I send with my Android device a picture to my Java server. I do this with a byte[]. Then I want to store it at my server. But this doesn't work right. The file has the right size, but when I want to open it, windows says: The file can't be opened. What's wrong?
FileOutputStream fos = new FileOutputStream("./images/"+IDfromPost+".png");
fos.write(buffer);
fos.close();
buffer is my byte[], IDfromPost an integer.
By the way. I display the length of the byte array at my phone and the server and both are the same.
It's not a problems with Android, you have to check how you decode the byte[] in your server to convert it to a ImageFile.
If you want more help, you have to update the post with the specification of you server.
Regards.
Related
I store the images to SQLite by converting the bitmap to byte array.
Should I do the same thing? Getting the byte array from bitmap, then to JSON, then to PHP, and finally to MySQL.
If yes, how can I do that? I could store strings to MySQL from the app, but couldn't do it on byte arrays.
just convert the byte array into Base64 ... base64 technically is a string, so JSON it to your webservice, there convert it back from Base64 ... and the rest is history
here is a link for converting image to Base64 in android : How to convert a image into Base64 string?
btw, other guys are right it's not so efficient to store the image itself inthe db, storing a reference would be much better ... unless you do not want your images to be right on the sd card, which is something else, security wise !
You can refer to this SO discussion that talks about uploading files to a server using Android.
As a matter of fact it is not recommended to store binary data into relational databases. Refer this SO Discussion. Rather a recommended way would be store the binary data on a server disk location as a file and simply place the path of the file within the database. This would prevent any corruption of data due to discrepancies in the database character set and encodings.
As you are willing to use another solution that is more good, i am explaining you the below procedure.
Instead of storing the image in the database, create a directory specifically for the images, after you successfully upload the image store the path of that image in your database. After that use that path to refer that image.
You can upload image via POST method, and then store reference in the database (ex:- images/img1.bmp)
Whenever you needed you can get file reference using http request(you need to code php for that request handling)
You can access image by using your servers public ip or domain for example : mydomain.com/app1/images/img1.bmp
This is just a one way to do it, so if you think about implementing look for file upload examples via POST
Hope this helps
Use Multipart file upload to send file to your web service (Use libraries like Android Asynchronous Http Client to make the job easy).Then you can encode the file in to Base64 and store in the database as text ,but it is not a best practice to store image files in database, you should save the image as file in the server and keep the path in MySql.
public static String imgToBase64(Bitmap bitmap) {
ByteArrayOutputStream out = null;
try {
out = new ByteArrayOutputStream();
// compress image
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, out);
out.flush();
out.close();
byte[] imgBytes = out.toByteArray();
return Base64.encodeToString(imgBytes, Base64.DEFAULT);
} catch (Exception e) {
return null;
} finally {
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Is a printstream appropriate for sending image files through a socket? I'm currently doing a homework assignment where I have to write a web proxy from scratch using basic sockets.
When I configure firefox to use my proxy everything works fine except images don't download. If I go to an image file directly firefox comes back with the error: The image cannot be displayed because it contains errors
Here is my code for sending the response from the server back to the client (firefox):
BufferedReader serverResponse = new BufferedReader(new InputStreamReader(webServer.getInputStream()));
String responseLine;
while((responseLine = serverResponse.readLine()) != null)
{
serverOutput.println(responseLine);
}
In the code above serverOutput is a PrintStream object. I am wondering if somehow the PrintStream is corrupting the data?
No, it is never appropriate to treat bytes as text unless you know they are text.
Specifically, the InputStreamReader will try to decode your image (which can be treated as a byte array) to a String. Then your PrintStream will try to encode the String back to a byte array.
There is no guarantee that this will produce the original byte array. You might even get an exception, depending on what encoding Java decides to use, if some of the image bytes aren't valid encoded characters.
I am getting my image as base 64 decoded string in my spring mvc application. e.g.
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABUUAAAkFCAYAAAD3GsjUAAAgAElEQVR4nOy9eXSb932vqc50fJs2Z+6ZOefeO2dmbm/aSW9ve+MmrZv2Nmmm7TROs7q2Yzl2HNWxtmihZNmSLMd24t=
I am trying save it as a png image:
byte[] imageByte = Base64.decodeBase64(base64encodedImage);
String directory = "D:\\Image Capture\\sample.png";
FileOutputStream outputStream = new FileOutputStream(directory);
outputStream.write(imageByte);
outputStream.flush();
outputStream.close();
but it is saving my image as
I am not able to figure out the reason. This encoded image is obtained using canvas.toDataUrl in javascript. It opens in browser tab perfectly.
Finally I have figured out.
Answer on this link helped.
The encoded Image I received:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABUUAAAkFCAYAAAD3GsjUAAAgAElEQVR4nOy9eXSb932vqc50fJs2Z+6ZOefeO2dmbm/aSW9ve+MmrZv2Nmmm7TROs7q2Yzl2HNWxtmihZNmSLMd24t=
The encoded image part starts after the phrase below:
data:image/png;base64,
I had to skip that string and then decoded image.
Also I have figured out from the same thread that the extra String shouldn't stop us from decoding.
In the same forum an approach is suggested that while converting encoded image user:
InputStream stream = new ByteArrayInputStream(Base64.decode(image.getBytes(), Base64.DEFAULT));
Refer to #Wand Maker's answer in the same thread.
I'm trying to send an image upload in a Qt server trough the socket and visualize it in a client created using Java. Until now I have only transferred strings to communicate on both sides, and tried different examples for sending images but with no results.
The code I used to transfer the image in qt is:
QImage image;
image.load("../punton.png");
qDebug()<<"Image loaded";
QByteArray ban; // Construct a QByteArray object
QBuffer buffer(&ban); // Construct a QBuffer object using the QbyteArray
image.save(&buffer, "PNG"); // Save the QImage data into the QBuffer
socket->write(ban);
In the other end the code to read in Java is:
BufferedInputStream in = new BufferedInputStream(socket.getInputStream(),1);
File f = new File("C:\\Users\\CLOUDMOTO\\Desktop\\JAVA\\image.png");
System.out.println("Receiving...");
FileOutputStream fout = new FileOutputStream(f);
byte[] by = new byte[1];
for(int len; (len = in.read(by)) > 0;){
fout.write(by, 0, len);
System.out.println("Done!");
}
The process in Java gets stuck until I close the Qt server and after that the file generated is corrupt.
I'll appreciate any help because it's neccessary for me to do this and I'm new to programming with both languages.
Also I've used the following commands that and the receiving process now ends and show a message, but the file is corrupt.
socket->write(ban+"-1");
socket->close(); in qt.
And in java:
System.out.println(by);
String received = new String(by, 0, by.length, "ISO8859_1");
System.out.println(received);
System.out.println("Done!");
You cannot transport file over socket in such simple way. You are not giving the receiver any clue, what number of bytes is coming. Read javadoc for InputStream.read() carefully. Your receiver is in endless loop because it is waiting for next byte until the stream is closed. So you have partially fixed that by calling socket->close() at the sender side. Ideally, you need to write the length of ban into the socket before the buffer, read that length at receiver side and then receive only that amount of bytes. Also flush and close the receiver stream before trying to read the received file.
I have absolutely no idea what you wanted to achieve with socket->write(ban+"-1"). Your logged output starts with %PNG which is correct. I can see there "-1" at the end, which means that you added characters to the image binary file, hence you corrupted it. Why so?
And no, 1x1 PNG does not have size of 1 byte. It does not have even 4 bytes (red,green,blue,alpha). PNG needs some things like header and control checksum. Have a look at the size of the file on filesystem. This is your required by size.
This problem seems to happen inconsistently. We are using a java applet to download a file from our site, which we store temporarily on the client's machine.
Here is the code that we are using to save the file:
URL targetUrl = new URL(urlForFile);
InputStream content = (InputStream)targetUrl.getContent();
BufferedInputStream buffered = new BufferedInputStream(content);
File savedFile = File.createTempFile("temp",".dat");
FileOutputStream fos = new FileOutputStream(savedFile);
int letter;
while((letter = buffered.read()) != -1)
fos.write(letter);
fos.close();
Later, I try to access that file by using:
ObjectInputStream keyInStream = new ObjectInputStream(new FileInputStream(savedFile));
Most of the time it works without a problem, but every once in a while we get the error:
java.io.StreamCorruptedException: invalid stream header: 0D0A0D0A
which makes me believe that it isn't saving the file correctly.
I'm guessing that the operations you've done with getContent and BufferedInputStream have treated the file like an ascii file which has converted newlines or carriage returns into carriage return + newline (0x0d0a), which has confused ObjectInputStream (which expects serialized data objects.
If you are using an FTP URL, the transfer may be occurring in ASCII mode.
Try appending ";type=I" to the end of your URL.
Why are you using ObjectInputStream to read it?
As per the javadoc:
An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream.
Probably the error comes from the fact you didn't write it with ObjectOutputStream.
Try reading it wit FileInputStream only.
Here's a sample for binary ( although not the most efficient way )
Here's another used for text files.
There are 3 big problems in your sample code:
You're not just treating the input as bytes
You're needlessly pulling the entire object into memory at once
You're doing multiple method calls for every single byte read and written -- use the array based read/write!
Here's a redo:
URL targetUrl = new URL(urlForFile);
InputStream is = targetUrl.getInputStream();
File savedFile = File.createTempFile("temp",".dat");
FileOutputStream fos = new FileOutputStream(savedFile);
int count;
byte[] buff = new byte[16 * 1024];
while((count = is.read(buff)) != -1) {
fos.write(buff, 0, count);
}
fos.close();
content.close();
You could also step back from the code and check to see if the file on your client is the same as the file on the server. If you get both files on an XP machine, you should be able to use the FC utility to do a compare (check FC's help if you need to run this as a binary compare as there is a switch for that). If you're on Unix, I don't know the file compare program, but I'm sure there's something.
If the files are identical, then you're looking at a problem with the code that reads the file.
If the files are not identical, focus on the code that writes your file.
Good luck!