0

I'm trying to transfer some image files from an android phone, over a socket, to a server. The only way I've found to do this on android so far is using a FileInputStream to read the image as a byte array and send this over the socket to be reconstructed on the server side. This works well, unfortunately Android (or java?) does not allow Metadata, in my case exif data, to be included in a FileInputStream. This means that my exif data is missing once the images are on the server.

I've tried to solve this issue using both ExifInterface, which doesn't seem to be able to read a lot of the exif data I need, and the Metadata library. The metadata library does seem to get all the exif data I want but I can't figure out how to write it out as bytes that can be sent over my stream, it only has a toString which gets rid of some of the data that needs to be transferred.

Ideally I'd love a way to transfer the file with it's metadata, however I'd be happy with a way to turn Metadata tags into bytes which I can add to my socket's output stream.

Here is the code which uploads files over the socket

FileInputStream in = new FileInputStream(lastSavedPath); byte[] buffer = new byte[1024]; int length = 0; while ((length = in.read(buffer, 0, buffer.length)) != -1){ outputStream.write(buffer, 0, length); } ExifInterface exifInterface = new ExifInterface(lastSavedPath); Metadata metadata = ImageMetadataReader.readMetadata(new File(lastSavedPath)); for (Directory directory : metadata.getDirectories()){ for (Tag tag : directory.getTags()){ Log.d("Socket Listener", tag.toString()); if (tag.toString().indexOf("Exif")>=0) Log.d("Socket exif", "Data"+exifInterface.getAttribute(tag.getTagName())); } } outputStream.flush(); Log.d("Socket Listener", "Data has been sent"); in.close(); socket.close();

Jamjarman
  • 1
  • 2
  • Your question is unclear. A `FileInputStream` just reads a file byte by byte. If on server side the Exif data is missing then they weren't included in the file you had read. May be you have read the wrong file? Please edit your question and include relevant code samples and more details what you do. – Robert Jul 27 '16 at 15:29
  • The android api does not allow for reading metadata from a stream http://stackoverflow.com/questions/12944123/reading-android-jpeg-exif-metadata-from-picture-callback. I can confirm that the files do infact have the exif data as I've downloaded them over adb to examine them. – Jamjarman Jul 27 '16 at 15:34
  • IMHO it is still unclear what you want to achieve and where it should be done (Android or server side). – Robert Jul 27 '16 at 15:42
  • I'm not sure what part is unclear. I have images on an android phone which include metadata. I need to transfer these images to the server with the metadata attached. I'm certainly open to any way to do this but given how android is locked down it seems to me the sending has to happen on the phone. I can't do this with FileInputStream because the android implementation of this class excludes metadata by design. – Jamjarman Jul 27 '16 at 15:47
  • For a common JPEG image the file data already contains the Exif metadata - you are just missing a way to read it out in Android. Therefore I don't understand what you are trying to do. Just send the JPEG file data to the server and extract the exif information there. No need to transfer them separately. – Robert Jul 27 '16 at 15:53
  • I apologize, I appear to have been mislead by the other thread I posted. I've confirmed that FileInputStream is in fact including the meta data so it must be disappearing somewhere else. – Jamjarman Jul 27 '16 at 16:16

1 Answers1

0

The issue here wasn't with android at all. I had read in another thread that the android FileInputStream did not include metadata but that was not the case. I believe now the issue was in my server side code. I've fixed the issue with the following code:

Server side (Needs to be in a try catch):

socket = new Socket(args[0], 8888);
     dataOutputStream = new DataOutputStream(socket.getOutputStream());
     dataInputStream = new DataInputStream(socket.getInputStream());
     dataOutputStream.writeUTF(args[1]);
     System.out.println("Saving image");
     FileOutputStream fileout = new FileOutputStream("/home/jamie/Documents/UMDSummer16/Thermal/TemporalAnalysisSensor/SocketTest/"+args[2]);
     byte[] bytes = new byte[1024];
     int count;
     while ((count = dataInputStream.read(bytes)) > 0){
         fileout.write(bytes);
     }
     fileout.close();
     dataInputStream.close();

Android side (also in a try catch):

FileInputStream in = new FileInputStream(lastSavedPath);
byte[] buffer = new byte[1024];
int length = 0;
while ((length = in.read(buffer, 0, buffer.length)) != -1) {
    outputStream.write(buffer, 0, length);
}
outputStream.flush();
Log.d("Socket Listener", "Data has been sent");
in.close();
socket.close();
Jamjarman
  • 1
  • 2