Is there any sample code to read thumbnail from Jpeg exif header? - c++

I am writing application using c++, in windows.
I want to get a thumbnail from jpeg, without decoding the whole image.
How Can I read thumbnail from jpeg exif header?
Can any one offer me a some sample code?
Many thanks!

Unsurprisingly the library is called libexif has win32 port, and there is sample code for reading thubnail from file

Don't bother. You can create tumbnails very fast from JPEGs. They are compressed using DCTs on 8x8 pixel blocks. So, get the DC component (i.e. 0,0) of each block and you have an 1/64th thumbnail without decoding. Further scaling should be fast since there are hardly any pixels left.

Related

Saving frames in opencv without compression

I'm trying to use the imwrite() OpenCV function. I want to save the frames with the .TIFF extension. The problem that I have is that the saved images are compressed so I can't use them. Any idea how I can escape this compression?
thanks in advance
Do not mind what sietschie says. The TIFF flag is hardcoded in the opencv binaries with a LZW compression. You can just turn this off (comment it out) or change it.
In:
3rdparty/libtiff/tiff.h
Remove this line:
#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */
Then compile. Presto.
Tiff options other than that are automatically set (8 bit, 16bit, color, rgb, rgba,etc) depending on your image
According to the documentation OpenCV only exposes a limited set of options for writing image files.
Non of which belongs to TIFF-Files.
So unless you want to use your own function or modify the OpenCV source, this is not possible.
I would suggest using another uncompressed format for saving the frames like PXM or BMP, unless you have some specific reasons to use TIFF-Files.
cv::imwrite("imagen.TIFF", bayer, {cv::IMWRITE_TIFF_COMPRESSION, 1,
cv::IMWRITE_TIFF_XDPI, 72,cv::IMWRITE_TIFF_YDPI,72});
The simplest way is recompiling OpenCV or direct using libtiff, but I consider as not very good idea changing 3rdparty/libtiff/tiff.h: after this modification you can't save compressed TIFFs at all with OpenCV, and under non-windows systems you usually have separate libtiff (not as a part of OpenCV).
I suggest simpler approach (still OpenCV recompilation, but you save possibility of writing compressed tiff and don't change libtiff directly):
saving uncompressed TIFFs with OpenCV

How to read .avi files C++

I want to read in an .avi video file for a program that I am making. I have the file location saved as a string. Is there any good tutorials on using .avi files in c++ or does anyone know who to read one in? Is it the same as normal files?
I have a previously asked SO question that goes into better detail but here is what I want to do:
I am making a program that will detect faces (though OpenCV) As of now I have been given a video processor program that will detect each face on a frame, and return the frame as a image and the CvRec of the faces. I want to take these faces and test them to validate that they are all actually faces.
After I have all the faces (tested) I want to then take the images and test them together. I test the faces on each frame for size and distance changes. If the faces pass this for a frame length of two seconds, then I want to crop the face and make it the subject of each frame.
After each frame is cropped I then want to save the new video file for the user.
Hopefully that helps. If anyone needs a better explanation please let me know.
First of all, a little background.
What is AVI?
AVI stands for Audio Video Interleave. It is a special case of the RIFF (Resource Interchange File Format). AVI is defined by Microsoft and it is the most common format for audio/video data.
I assume you would want to read a avi file and decode the compressed video frames. AVI file is just like any other normal file and you can use fread()(in C) or iostream(in C++) to open an avi file and read it contents. But the contents of an avi file are video frames in a compressed format. The compression allows video content of bigger sizes to be efficiently packed in less memory space.To make any sense of this compressed data you would have to decode the encoded data format.You will have to study the standard which describes how AVI encoding is done and then extract and decode the frames. this raw video data now when fed to a video device will be displayed in video format.
It seems you are staying within OpenCV so things are easy. If OpenCV is compiled properly it is capable of delegating io/coding/decoding to other libraries. Quicktime and others for example, but best is to use ffmpeg. You open, read and decode everything using the OpenCV API which gives you the video frame by frame.
Make sure your OpenCV is compiled with ffmpeg support and then read the OpenCV tutorial on how to read/write AVI files. It's really easy.
Getting OpenCV to be built with ffmpeg support might be hard though. You might want to switch to an older version of OpenCV if you can't get ffmpeg running with the current one.
Personally i would not spent time trying to read the video by yourself and delegate the task to OpenCV. That's how it is supposed to be used.

GetDIBits() is failing with PNG compression

I am trying to get the size of PNG image (Without storing into file). I am using this code as reference. When calling GetDIBits(), size of image would get updated into bi.biSizeImage. Everything works fine when bi.biCompression is BI_RGB. Then I have changed the compression mode from BI_RGB to BI_PNG; GetDIBits() started to fail. Please help me to solve this.
According to http://msdn.microsoft.com/en-us/library/dd145023%28VS.85%29.aspx:
"This extension is not intended as a means to supply general JPEG and PNG decompression to applications, but rather to allow applications to send JPEG- and PNG-compressed images directly to printers having hardware support for JPEG and PNG images."
using GetDIBits() with BI_PNG is not allowed.

How to read embed thumbnail from jpeg images?

I am writing a thumbnail viewer in c++.
I first make use of EXIF information to retrive an image's thumbnail, but the thumbnail in the EXIF is bad, with black bands. So I want to get the jpeg's embedded thumbnail, how can I do this?
Another question:
does jpeg's embeded thumbnail equal to EXIF thumbnial?
If the EXIF thumbnail is bad, you can generate your own from the JPEG itself, without needing to completely decode the JPEG.
Look for the source code for EPEG. It's part of the Enlightenment project on SourceForge, and was part of the old EFL a year ago. You can still dig it up from some old SVN commits or from a source tarball that might be floating around.
Basically, what EPEG does, is it collects the DCT coefficients from the image, and performs a rescaling operation on them. The DCT coefficient is normally used as the base coefficient for an 8x8 block of pixels. You can treat it as one pixel. As a result, you have a (computationally free) thumbnail exactly 1/8th the size of the original image. Rescale it as you would any image data to the desired dimensions.
In the majority of cases where people talk about JPEG files having thumbnails, they mean the file is JPEG-EXIF and the EXIF data contains a thumbnail image.
However, it is true to say that JFIF 1.02 supports a thumbnail image. The thumbnail may be stored in the JFIF APP0 marker or an official JFXX APP0 extension marker; the thumbnail may be uncompressed RGB, JPEG or palletted. See
http://en.wikipedia.org/wiki/JPEG_File_Interchange_Format#JFIF_segment_format for details.
The fastest and recommended ways are libraries.
For example, www.exiv2.org can provide you with the library for embedded thumbnail and EXIF info extraction. There is a lot of alternatives, but I think this one is a good solution.
www.exiv2.org in my eyes is a bad solution. There are just too many deps to other projects. Expat and zlib for instance. If you want to come up with a lightweight solution that you can support on your own, I would recommend to write your own EXIF decoder.

Does anyone know of a program/method to compress just certain parts of a PNG image w/o slicing it?

Please help! Thanks in advance.
Update: Sorry for the delayed response, but if it is helpful to provide more context here, since I'm not sure what alternative question I should be asking.
I have an image for a website home page that is 300px x 300px. That image has several distinct regions, including two that have graphical copy on top of the regions.
I have compressed the image down as much as I can without compromising the appearance of that text, and those critical regions of the image.
I tried slicing the less critical regions of the image and saving those at lower compressions in order to get the total kbs down, but as gregmac posted, the sections don't look right when rejoined.
I was wondering if there was a piece of software out there, or manual solution for identifying critical regions of an image to "compress less" and could compress other parts of the image more in order to get the file size down, while keeping those elements in the graphic that need to be high resolution sharper.
You cannot - you can only compress an entire PNG file.
You don't need to (I cannot think of a single case where compressing a specific portion of a PNG file would be useful)
Dividing the image in to multiple parts ("slicing") is the only way to compress different portions of a image file, although I'd even recommend again using different compression levels in one "sliced image", as differing compression artefacts joining up will probably look odd
Regarding your update,
identifying critical regions of an image to "compress less" and could compress other parts of the image more in order to get the file size down
This is inherently what image compression does - if there's a bit empty area it will be compressed to a few bytes (using RLE for example), but if there's a very detailed region it will have more bytes "spent" on it.
The problem sounds like the image is too big (in terms of file-size), have you tried other image formats, mainly GIF or JPEG (or the other PNG format, PNG-8 or PNG-24)?
I have compressed the image down as much as I can without compromising the appearance of that text
Perhaps the text could be overlaid using CSS, rather than embedded in the image? Might not be practical, but it would allow you to compress the background more (if the background image is a photo, JPEG might work best, since you no longer have to worry about the text)
Other than that, I'm out of ideas. Is the 300*300px PNG really too big?
It sounds like you are compressing parts of your image using something like JPEG and then pasting those compressed images onto a PNG combined with other images, and the entire PNG is sent to the browser where you split them up.
The problem with this is that the more you compress your JPEG parts the more decompression artifacts you will get. Then when you put these low quality images onto the PNG, which uses deflate compression, you will actually end up increasing the file size because it won't be able to compress well.
So if you are keen on keeping PNG as your file format the best solution would be to not compress the parts using JPEG which you paste onto your PNG - keep everything as sharp as possible.
PNG compresses each row separately unless you have used a "predictor" in the compression.
So it's best to keep your PNG as wide as possible with similar images next to each other horizontally rather than under each other vertically.
Perhaps upload an example of the images you're working with?