I recently began using Magick++ (C++ API for ImageMagick) with the goal of creating a website that could display randomly generated images. I am trying to write a CGI script which would create a JPEG Image, set the color of its pixels, and then return the image information as Content-type: image/jpg.
Reading through the documentation, I only find functions for writing image files to disk. I do not see one which would do what I am hoping to do, along the lines of std::cout << Image or std::cout << Blob
My goal is to be able to display the image generated by the script in a webpage, without needing to write the image to disk.
I know that PerlMagick has a display function which does what I am trying to do - I am wondering if I can do the same with Magick++.
I think you are looking for blobs - Binary Large Objects. Basically, you create an image of type Image and a blob of type Blob. You populate your image either by reading from a file or generating your random data, then you write your image to the blob (to encode it) and you can then write that to the user's browser.
Please excuse my useless C/C++ skills...
Image image;
Blob blob;
// set type to JPEG
image.magick("JPEG");
// generate/read/fill image here
image.read("image.jpg");
// encode image as JPEG
image.write(&blob);
// now send MIME type to browser
std::cout << "Content-type: image/jpeg" << CRLF;
// ... followed by blob
write(1,(char*)blob.data(),blob.length());
Related
I have a script that displays all images found on the server and checks on a regular basis.
From time to time, it downloads an image that hasn't been completely uploaded yet resulting in a half JPEG with the lower part being gray.
I'm using a qbyteAray to store received data and load in in a QPixmap with :
QByteArray bytes = reply->readAll(); // bytes
qDebug() << "loading pixmap" ;
qDebug() << pixmap.loadFromData(bytes);
I would like to detect if the load failed and retry 500ms later, but I cannot find a solution to verify if the pixmap contains valid JPG data.
The loadFromData returns TRUE but inside this method I get a Warning, this is the Application Output for the lines above:
loading pixmap
Corrupt JPEG data: premature end of data segment
true
Is there any way to check/bool if the pixmap has corrupted data?
Solution
As suggested by vsz, if images are natural images and not graphics, it's very unlikely that pixels of the lower row are the exact gray of an invalid JPG. Thus it it possible to determine if an image is valid with these lines in a method :
QImage img = pixmap.toImage();
if( img.pixel(img.width()-1,img.height()-1 ) == 4286611584 && img.pixel(img.width()/2,img.height()-1 ) == 4286611584 && img.pixel(0,img.height()-1 ) == 4286611584 ) return false; //invalid color : 4286611584 (default gray jpg)
else return true;
There are several possible messages on corrupt JPEG data:
Corrupt JPEG data: premature end of data segment
Corrupt JPEG data: 12 extraneous bytes before marker 0xd9
Corrupt JPEG data: bad Huffman code
The nice vsz way would unfortunately not catch the 2 other errors I have encountered as no default gray used for these in the bad image area.
But it is better for the 1st error than what I propose below to try to report on all errors but fails in multithread.
In Qt 4.8.6, the "Corrupt JPEG data" errors were directly sent to the console, no way to catch them from qt code.
Not sure when it changed, but in Qt5.5.1, these messages go through the MessageHandler, so it is possible to catch them.
Loading only pictures from disk in the software, I use the following to know which picture is corrupted.
In the MessageHandler, I detect any "Corrupt JPEG data" message and set a global variable corrupt_jpg_detected to true.
if(msg.contains("Corrupt JPEG data"))
setCorrupt_jpg_detected(&corrupt_jpg_detected, true);
Then in the code where I read the image, I add the following:
QImage img(path_to_my_image) //read image file => will sent "Corrupt JPEG data" error if image corrupted
if(corrupt_jpg_detected) "code to print in log file / inform user of image corruption, can include path_to_my_image"
This has a strong weakness, if you are using multithread to load pictures (using QtConcurrent::mapped for example) then the first of thread testing the if(corrupt_jpg_detected) will print image info, this will most likely not be the thread which encountered the corrupted image...
The decoding of JPEG data happens in the external library called "libjpeg", so the Qt classes QPixmap and QImage don't do anything about it, as they receive an image which was decoded by libjpeg. If libjpeg gives an image to QPixmap, then QPixmap regards it as success.
There was a request back in 2009 for Qt to do something about it (see this post) but it seems that nothing has been done regarding this issue.
This means that it's highly likely that you are on your own, and unless QPixmap and QImage will be expanded with new features in future releases, you can't verify the integrity of a jpeg image just by calling a method within these classes.
I would suggest one of the following:
access libjpeg by yourself
check the color of the last row of the image. It's unlikely that every pixel of the lowest row will be the same shade of gray as in the case of a corrupted image. This depends on your application, but if you deal with natural images (photos) then this is the solution I would advise.
I am using opencv 3.0 version which has support for creating HDR images and trying to produce an HDR image using three images at different exposure.
And i found this tutorial of opencv.
http://docs.opencv.org/master/d3/db7/tutorial_hdr_imaging.html#gsc.tab=0
Its easy to understand but it takes paramter like exposure times for images.
How do i will get this exposure time ? I have only images. Do any one has tried it already ?
Thanks
Image exposure time is in EXIF data. In the explorer window right click the image, go to properties, you will see some of the EXIF data including exposure time if the image has that data.
or you can write a program to extract metadata to a txt file. I used python exifread() to read exposure time.
https://pypi.python.org/pypi/ExifRead
A very beginner in OpenCV
I am trying to implement text steganography: Trying to hide a text message in an image.
What I do is, I hide each of the characters from the text message by modifying the pixels in the image. For each of the characters I take the binary representation of the character and replace the last bit of a pixel with the LSB of the character, and gain last bit of another pixel with the 2nd bit of the character, and so on .... for the whole message.
After this encryption of the text into the image I store it on the disk using cv::imwrite.
This image is again read in by another routine and decrypts it doing the reverse opeartions used for encrypting.
But, the problem is decryption is not working if i read in the image(encrypted image) whihc is stored using cv::imwrite.
But, it works if I pass-on the encrypted matrix (cv::Mat) object to the decryption routine rather than reading a image again.
Seems, something is getting changed when i store the encrypted matrix into an image.
Not sure what is going on behind the scenes. Any help is appreciated.
It sounds like you loose the information when saving.
According to the documentation of imwrite function ( imwrite() documentation ) the function chooses the format of the image based on the extension of the filename you are giving. Could it be that you are using a lossy file format such as JPEG (*.jpg)? instead try using a .png which uses a lossless compression to save the data.
EDIT:
You can use different approach for steganography specially designed for jpeg images: http://www.sav.sk/journals/uploads/0317153109jo-mo.pdf
I have some images (in PNG and JPG format), stored as blobs in the database. I am retrieving them with a query and would like to take action by reading the metadata without writing the image to disk.
I am looking for the file type and image width.
You should be abe to convert the data to a ColdFusion Image type using the ImageNew function as documented here (set the source to be the variable you pulled out of the query).
Once you have the image, you can use the ImageInfo function to retrieve image properties.
This will give you the width. CF won't tell you the original file format, though--it might be easiest to look at magic numbers for that. Wikipedia gives a good summary of what those are and what the values for jpeg and png are: http://en.wikipedia.org/wiki/Magic_number_(programming)
I'm using this command to ftp upload a png image. But when I upload the image is not visible it looks like currupted even if I download it I can't view the image.
Here is the code
ftp.storlines('STOR ' + 'Simple.png', open('Simple.png', 'rb'))
here is the uploaded file
http://llgrow.co.nf/Simple.png
That's because ftp.storlines() is sending the file in ascii mode, you should use ftp.storbinary() for an image file (binary mode):
F=open("Simple.png","rb")
ftp.storbinary('STOR image.png',F,1024)
Try using storbinary()...
Because it takes the binary values of that image... So that no pixel values are messed up...
Since image files contain pixels... Need to store the exact X,Y positions of the pixels.
So storbinary() does that by default.