Writing IPTC data to jpg file - java

I would like to write IPTC data, such as title, description or keywords to an jpg file, but it does not work. If i run the sample code a second jpg file is writen, but no sample data. I am using the commons imaging library from Apache:
http://commons.apache.org/proper/commons-imaging/
Here is the sample code:
TiffImageMetadata metadata = ((JpegImageMetadata)Imaging.getMetadata(new File(JPG_PATH +
"\\IMGP5996_empty.jpg"))).getExif();
ExifRewriter rewriter = new ExifRewriter();
TiffOutputSet outputSet = metadata.getOutputSet();
TiffOutputDirectory exif = outputSet.getOrCreateExifDirectory();
exif.add(MicrosoftTagConstants.EXIF_TAG_XPAUTHOR, "TEST_AUTHOR");
exif.add(MicrosoftTagConstants.EXIF_TAG_XPCOMMENT, "TEST_COMMENT");
exif.add(MicrosoftTagConstants.EXIF_TAG_XPSUBJECT, "TEST_SUBJECT");
exif.add(MicrosoftTagConstants.EXIF_TAG_XPTITLE, "TEST_TITLE");
exif.add(MicrosoftTagConstants.EXIF_TAG_XPKEYWORDS, "TEST_KEYWORD");
FileOutputStream fos=new FileOutputStream(new File(JPG_PATH + "\\IMGP5996_empty-2.jpg"));
rewriter.updateExifMetadataLossy(jpgFile, fos, outputSet);
Can anyone help me?

I think at this moment, it is not possible to write (with commons imaging) IPTC metadata to a jpg file:
http://commons.apache.org/proper/commons-imaging/todo.html

It would be straightforward, but not trivial, to do this on your own. You would need to rewrite the EXIF APPn Market, but this could be down without modifying the rest of the compressed data stream. You would need to read the EXIF standard to understand how the metadata tags are encoded.

Thank you all for your reply
I have fond a solution with iim4j:
http://iim4j.sourceforge.net/
Good library but poor documenation

Related

I get a non playable MP4 file when created with Mp4Parser Java API

I'm studying Mp4Parser API (Mp4Parser GitHub) and try to learn how it's working. I first tried to create an MP4 by "copying" the highest level tags into a new file.
If I get a similar file, it's unfortunately not "the same file" and result can't be played.
My dirty (it's just a quick try) code is:
public void copy(String videoFilePath) throws IOException {
File videoFile = new File(videoFilePath);
File videoPro2 = new File("/tmp/output.mp4");
if (videoPro2.exists())
videoPro2.delete();
videoPro2.createNewFile();
FileOutputStream fos = new FileOutputStream(videoPro2);
IsoFile isoFile = new IsoFile(new FileInputStream(videoFilePath).getChannel());
IsoFile pro2 = new IsoFile(new FileInputStream(videoPro2).getChannel());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
pro2.addBox(Path.getPath(isoFile, "ftyp[0]"));
pro2.addBox(Path.getPath(isoFile, "free[0]"));
pro2.addBox(Path.getPath(isoFile, "moov[0]"));
pro2.addBox(Path.getPath(isoFile, "mdat[0]"));
pro2.getBox(Channels.newChannel(baos));
baos.writeTo(fos);
isoFile.close();
pro2.close();
baos.close();
return;
}
I tested my original MP4 with AtomicParsley, saw there were in that order, a ftyp, a free, a moov and an mdat tags.
My method basically aims to get these four tags and puts them into the destination file to "make an exact copy". Or that's what I was expecting, but it's not the case.
Firstly, output.mp4 is not playable, but comparing the hex dumps of input and output... almost everything is different, except ftyp and free. Why?
I can see that tag size are not similar neither..
Obviously, my goal is not to "copy" files, but understand Mp4Parser API as I'd like to use it in a real project. But this copy method is a starter for me to understand how this works, as I'm not familiar with MP4 specification.
Thanks
Ok, my fault.
There was an UUID tag I missed in the original footage between moov and mdat tags. Copying the UUID tag using
pro2.addBox(Path.getPath(isoFile, "uuid[0]"));
just before adding the mdat atom does the trick.
Sorry for this :)

.jpg out of .cgi with java (IP Webcam)

hy there, i hope i can explain my question:
i´ve an ip webcam and i want to read&save a .jpg file out of the path
webacm-ip-adr:8084/snapshot.cgi
i´ve little java experience and would like to program it in processing to keep it simple:
i´ve found this link:
https://www.java.net/node/702486
but its a slight overkill for me to understand it would be great if i can work with the 2 processing examples: web/loadingimages and net/httpClient
or do i make an logic mistake and its not solveable this way ?
You can use java lib "Apache Commons IO" to done it.
My Simple Code:
URL url = new URL("http://webacm-ip-adr:8084/snapshot.cgi");
InputStream input = url.openStream();
String jpg = "sample.jpg";
FileOutputStream output = new FileOutputStream(jpg);
IOUtils.copy(input, output);
Class "IOUtils" is a common tool for IO stream operation in commons-io jar.

Decoding of old style JPEG-in-TIFF data is not supported

I need to display the 3rd page of scanned tiff files. i used the code
TIFFReader reader = new TIFFReader(new File(pathOfFile));
RenderedImage image = reader.getPage(2);
its sometimes work. and show error : Decoding of old style JPEG-in-TIFF data is not supported.
I used aspriseTIFF.jar
then how i solve this problem.
please reply.
thanks in advance
The problem you have run into is that "old style" JPEG compression in the TIFF format (compression == 6), is not supported in the library you use.
This is quite common I guess, as "old-style" JPEG compression is deprecated in TIFF, because it was never fully specified. And because of this under-specification, various vendors implemented it in different, incompatible ways. Support was dropped in favor for TIFF compression 7, JPEG.
Unfortunately, old TIFF files using this compression still exists, so you need to find another library. The good news is that you can use ImageIO and a proper plug-in.
Using a TIFF ImageReader plug-in, like the one from my TwelveMonkeys ImageIO open source project, you should be able to do this:
// Create input stream
try (ImageInputStream input = ImageIO.createImageInputStream(file)) {
// Get the reader
ImageReader reader = ImageIO.getImageReaders(input).next();
try {
reader.setInput(input);
// Read page 2 of the TIFF file
BufferedImage image = reader.read(2, null);
}
finally {
reader.dispose();
}
}
(sorry about the try/finally boiler-plate, but it is important to avoid resource/memory leaks).

DICOM JPEG compression not yet supported in Android

DicomDroid.jar used to open a .dcm formated image in my Android application. I got the follwing exception when try to open it.
java.io.IOException: DICOM JPEG compression not yet supported
Adding my code below
try {
// Read the imagefile into a byte array (data[])
File imagefile = new File(path);
byte[] data = new byte[(int) imagefile.length()];
FileInputStream fis = new FileInputStream(imagefile);
fis.read(data);
fis.close();
// Create a DicomReader with the given data array (data[])
DicomReader DR = new DicomReader(data);
} catch (Exception ex) {
Log.e("ERROR", ex.toString());
}
What can be done to avoid this error?
Thanks in advance.
The cause is pretty obvious. That DICOM library doesn't support that particular kind of DICOM file.
There's not much you can do about it ... unless you are prepared to enhance the library yourself.
But I think you have probably made a mistake in setting up your instrument to generate DICOM files with JPEG compression. JPEG is lossy, and best practice is to capture and store images with the best resolution feasible. If you need to downgrade resolution to reduce bandwidth, it would be better to
save a high resolution DICOM,
convert the DICOM to a low resolution JPG, and
send the JPEG.
Another option is to get the Dicom file in an uncompressed format (ej: Explicit VR Little Endian). This is the simplest dicom file format and every dicom library has support for such format.
So, when you get your Dicom file from your PACS, force this transfer syntax. This way, your dicom library will be able to deal with the image file.

How can I decode OGG vorbis data from a ByteBuffer?

The libraries I founded so far only have methods to decode from a file or InputStream. I have a ByteBuffer with OGG vorbis data and I need it decoded to PCM without having to write it to a file first.
There seem to be 2 parts to this problem.
1) Getting Java Sound to deal with OGG Vorbis format.
2) Avoiding the File.
For (1), the Java Sound API allows the addition of extra formats via the Service Provider Interface. The idea is to put an encoder/decoder into a Jar and use a standard path and format of file to identify the class that does the encoding/decoding.
For (2), it is simply a matter of supplying an InputStream and required AudioFormat to the relevant methods of the AudioSystem static functions. E.G. (Pseudo code..)
byte[] b = byteBuffer.array();
ByteArrayInputStream bais = new ByteArrayInputStream(b);
InputStream is = new InputStream(bais);
AudioInputStrream aisOgg = AudioSystem.getAudioInputStream(is);
AudioInputStrream aisPcm = AudioSystem.
getAudioInputStream(pcmAudioFormat, aisOgg);
You can use ByteArrayInputStream which is a subclass of InputStream.
If your stream is very large you probably will have to write to file.

Categories