Dump raw image data - c++

I have an image stored in memory in the form of raw bytes i.e. I have a char* pointing to the memory location of the image data. Now, I need to somehow validate if the image data is legitimate.
What I have currently tried is to simply dump the bytes into a file. I tried dumping into 3 types of files, but no luck:
std::ofstream ofs;
ofs.open("Image.raw", std::ofstream::out);
ofs.write((char*)imgData, imageInfo.imageLen);
ofs.close();
// Have also tried "Image.tiff" and "Image.ppm"
Is there any way to view the contents? Just to mention, I am writing this code on Win platform. A few years back, I remember doing the similar thing on MAC OS X, which yielded successful results!.

You can write it straight out as RGB in binary like you already have - say to a file called image.rgb.
Then use ImageMagick, which is installed on most Linux distros, and available for OSX and Windows to convert it to PNG, JPEG or something more common:
convert -size 300x400 -depth 8 image.rgb result.png
or
convert -size 300x400 -depth 8 image.rgb result.jpg
You will need to tell ImageMagick the dimensions of the image as above because they are obviously not embedded within a raw file like they would be in a JPEG or PNG with a header.
If the filename you choose does not end in .rgb, you will need to prefix it with RGB: like this
convert -size ... RGB:something.bin result.png

Related

Create a grayscale image from 16-bit data using C++

I have an array of 16-bit values and I want to create an image (such as BMP) so that I can view it. Does anyone have suggestions of how to do this?
Thanks
Say your image is 200px by 100px. Write the 20,000 16-bit vales to a binary file.
At the commandline, run ImageMagick:
magick -depth 16 -size 200x100 gray:yourFile.bin image.png
Or, if you want a JPG
magick ... image.jpg
For a tiny bit more effort, you could write a 16-bit PGM file which would have the benefit that it contains its dimensions and bit depth in a small ASCII header so the conversion in ImageMagick is simpler, and other programs such as GIMP can read it:
magick yourFile.pgm image.jpg
The header would be:
P5
200 100
65535
... binary data as above ...
See Wikipedia NetPBM article.

How to quickly save an unsigned char array to image file?

I have an array of unsigned char array which is actually a RGBA raw image. How to export it into the image file? Any image file format is OK.
You can write it straight out as RGBA in binary. Then use ImageMagick, which is installed on most Linux distros, and available for OSX and Windows to convert it to PNG or something more common:
convert -size 300x400 -depth 8 binary.rgba result.png
You will need to tell ImageMagick the dimensions of the image as above because they are obviously not embedded within a raw file like they would be in a JPEG or PNG with a header.
If the filename you choose does not end in .rgba, you will need to prefix it with RGBA: like this
convert -size ... RGBA:something.bin result.png
If you are using OSX, I personally think homebrew is the easiest way to install ImageMagick...
brew install imagemagick
I think your best bet is just saving it to a .bmp file, because basically bitmap is a (upside down) array of rgba values. So you can just write a simple header and then write it line by line to the file.
For a header you'd have to write the file header first, and after that there is the DIB header. There are multiple options for this, but i'd suggest the simple one.
The bitmap format has support for a lot of fancy stuff, but most of it is optional and for your propose not necessary.

Read RGB triplets of JPEG files in C

to read bmp files we may use this http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx
as the header file and then get rgb triplets. How to get the rgb triplets of jpeg file, is there any such header file available. Please share the link if any.
The JPEG file format does not store the rgb triplets directly but it uses some sort of image compression. The file actually contains blocks of 64 (if I remember correctly) pixels which are attributed with a cosine pattern defining the actual colors.
You really should use a library (libjpeg, imagemagick, gd, ... e.g., depending on your use case) to read and decode the files and generate the rgb triplets in memory.
According to the answer to this question on MSDN, you could use the GDI+ component, which can load not only BMP, but JPG and other image formats too. From it, you will get a memory bitmap.
Here is an example on how to do that.
Check this library: libjpeg. This library implements JPEG image encoding, decoding,
and transcoding.

How to write YUV 420 video frames from RGB data using OpenCV or other image processing library?

I have an array of rgb data generated from glReadPixels().
Note that RGB data is pixel packed (r1,g1,b1,r2,g2,b2,...).
How can I quickly write a YUV video frame using OpenCV or another C++ library, so that I can stream them to FFMPEG? Converting RGB pixel to YUV pixel is not a problem, as there are many conversion formula available online. However writing the YUV frame is the main problem for me. I have been trying to write the YUV video frame since the last few days and were not successful in doing that.
This is one of my other question about writing YUV frame and the issues that I encountered: Issue with writing YUV image frame in C/C++
I don't know what is wrong with my current approach in writing the YUV frame to a file.
So right now I may want to use existing library (if any), that accepts an RGB data, and convert them to YUV and write the YUV frame directly to a file or to a pipe. Of course it would be much better if I can fix my existing program to write the YUV frame, but you know, there is also a deadline in every software development project, so time is also a priority for me and my project team members.
FFmpeg will happily receive RGB data in. You can see what pixel formats FFmpeg supports by running:
ffmpeg -pix_fmts
Any entry with an I in the first column can be used as an input.
Since you haven't specified the pixel bit depth, I am going to assume it's 8-bit and use the rgb8 pixel format. So to get FFmpeg to read rgb8 data from stdin you would use the following command (I am cating data in but you would be supplying via your pipe):
cat data.rgb | ffmpeg -f rawvideo -pix_fmt rgb8 -s WIDTHxHEIGHT -i pipe:0 output.mov
Since it is a raw pixel format with no framing, you need to subsitite WIDTH and HEIGHT for the appropriate values of your image dimensions so that FFmpeg knows how to frame the data.
I have specifed the output as a MOV file but you would need to configure your FFmpeg/Red5 output accordingly.
OpenCV does not support the YUV format directly, as you know, so it's really up to you to find a way to do RGB <-> YUV conversions.
This is a very interesting post as it shows how to load and create YUV frames on the disk, while storing the data as IplImage.
ffmpeg will write an AVI file with YUV but as karl says there isn't direct support for it in openCV.
Alternatively (and possibly simpler) you can just write the raw UYVY values to a file and then use ffmpeg to convert it to an AVI/MP4 in any format you want. It's also possible to write directly to a pipe and call ffmpeg directly from your app avoiding the temporary yuv file
eg. to convert an HD yuv422 stream to a h264 MP4 file at 30fps
ffmpeg -pix_fmt yuyv422 -s 1920x1080 -i input.yuv -vcodec libx264 -x264opts -r 30 output.mp4

What options for convert (ImageMagick or GraphicsMagick) produce the smallest (filesize) PNG?

ImageMagick creates some pretty large PNGs. GraphicsMagick is a lot better, but I'm still looking for the best options to use with convert to obtain the smallest filesize png.
I have here a large png with a small filesize, and passing this through IM convert I have been unable to reach that filesize, let alone get it smaller. With GM convert I can get it slightly smaller but I'm looking for improvements, generically for any image I come across.
gm convert -quality 95 a_png.png gm.png
convert -quality 95 -depth 8 a_png.png im.png
gm identify *
a_png.png PNG 2560x2048+0+0 PseudoClass 256c 8-bit 60.1K 0.000u 0:01
gm.png[1] PNG 2560x2048+0+0 PseudoClass 256c 8-bit 60.0K 0.000u 0:01
im.png[2] PNG 2560x2048+0+0 DirectClass 8-bit 130.2K 0.000u 0:01
What options for convert produce the smallest PNG filesize?
(Yes, I'm familiar with OptiPNG, PNGOUT and Pngcrush. But I'm after something that will be available without question on every *nix box I happen to be on.)
Looks like you and me are looking for the same answer. Unfortunately there doesn't seem to be many people out there with a good knowledge of GraphicsMagick. This is what I have learned so far,
The quality operator doesn't properly work for any image other than JPEG's. For me it just made the file size bigger when used on PNG's and GIF's.
I have done this to my PNG and GIF files to reduce their size:
gm convert myImage.png +dither -depth 8 -colors 50 myImage.png
+dither stops any dithering of the image when the colors are reduced. (this reduces the file size)
-depth 8 is probably unnecessary as most PNG files are already depth 8.
-colors 50 reduces the number of colors in the image to 50, this is the only way to really reduce the size of a image stored in a lossless format like PNG or GIF.
Obviously for the best image quality/size ratio you cant just reduce the image depth or number of colors without knowing the current depth and number of colors. To determine this information I am doing the following
gm identify -format "file_size:%b,unique_colors:%k,bit_depth:%q" myImage.png
For my image; this returns
file_size:100.7k,unique_colors:13455,bit_depth:8
The problem is when GraphicsMagick reduces colors it always reduces to at least 255, so you can't set the number of colors to 300 for example. Also there seems to be an issue with the alpha channel for PNG files; If the image has transparency in it, reducing colors replaces these colors with transparent; with imagemagick it does not do this.
I just came across this question again so I'll update, GraphicsMagick and ImageMagick have a serious problem. They cannot write out PNG images using a tRNS chunk which means if you try to read in an image that has a tRNS chunk and then write it out, the image will be much bigger. GM is not the best tool for compressing images. You need to use a separate tool such as OptiPNG to compress PNG's again after using Image/GraphicsMagick. I am getting up to 60% smaller files when using OptiPNG after running GraphicsMagick on an image.
Also I was wondering if you have encountered a problem regarding RGBA images and bit depth. For some images I am getting an "Invalid bit depth" exception. I can't see any reason why.
I haven't found a way to do it in the command line, but i did find this free website (http://tinypng.org/) that does an excellent job, my test image got a 71% reduction, final size was only 29% of the original. It looks like you can give it 20 images at a time. I'm looking into how they do it.
http://tinypng.org/