Search code examples
javaimage-processingamazon-s3aws-java-sdkapache-commons-imaging

How to get outputstream from an S3Object?


My goal is to fetch an object (image) from S3, change the metadata of the file, and replace it with new file that has changed metadata.

For changing the metadata I am using commons imaging library. I have coded the sample below that works as expected but does not deal with S3.

File newFile = new File("newImage2.jpg");
OutputStream os = new BufferedOutputStream(new FileOutputStream(newFile))
InputStream isNew = new BufferedInputStream(new FileInputStream(newFile))
InputStream is = new BufferedInputStream(new FileInputStream(new File("newImage.jpg")))
try {
            String xmpXml = "<x:xmpmeta>" +
            "\n<Lifeshare>" +
            "\n\t<Date>"+"some date"+"</Date>" +
            "\n\t<Latitude>"+"somelat"+"</Latitude>" +
            "\n\t<Longitude>"+"somelong"+"</Longitude>" +
            "\n\t<Altitude>"+"somealt"+"</Altitude>" +
            "\n\t<Z>"+"someZ"+"</Z>" +
            "\n\t<X>"+"someX"+"</X>" +
            "\n\t<Y>"+"Some y"+"</Y>" +
            "\n</Lifeshare>" +
            "\n</x:xmpmeta>";
            JpegXmpRewriter rewriter = new JpegXmpRewriter();
            rewriter.updateXmpXml(is,os, xmpXml);
            String newXmpXml = Imaging.getXmpXml(isNew, "newImage2.jpg");
            println newXmpXml
        }
finally {
   is.close()
   os.close()
}

The above works since I can run exiftool on the newimage2.jpg and view the set metadata properties:

$ exiftool newImage2.jpg | grep "Lifeshare"
Lifeshare Date                  : some date
Lifeshare Latitude              : somelat
Lifeshare Longitude             : somelong
Lifeshare Altitude              : somealt
Lifeshare Z                     : someZ
Lifeshare X                     : someX
Lifeshare Y                     : Some y

Question

How can I do the same using an object on S3 using AWS S3 SDK? The updateXmpXml method above requires OutputStream as a second parameter. However, I don't see any outputstream class in the AWS sdk http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/allclasses-noframe.html


Solution

  • http://docs.aws.amazon.com/AmazonS3/latest/dev/RetrievingObjectUsingJava.html

    using apache ioutils

    OutputStream os = new ByteArrayOutputStream();
    
    
        AmazonS3 s3Client = new AmazonS3Client(new ProfileCredentialsProvider());        
        S3Object object = s3Client.getObject(
                          new GetObjectRequest(bucketName, key));
        InputStream in= object.getObjectContent();
        IOUtils.copy(in, out);
    
        in.close();
        out.close();