Printing a QImage has color distortion
-
Hello,
I've been using Qt to develop some home made applications for a while now, but I'm in my first experience with printing images (I've done some B&W stuff in the past, but nothing major).
My printer prints on small plastic cards. I'm simply creating a QImage object from a JPG file on my drive and calling QPainter::drawImage to draw the picture. However, the end result is pretty bad in terms of colors.! Here are copies of the printed result. One of them is printed through my Qt application and the other is printer through another software (I tried scribus, which uses Qt).
Does anyone have any experience with printing images with Qt and could leave me a few clues into making my printing better ?
Thanks,
BasiC
-
Hi
Oh, you have just enabled zombie mode printing. ! :)Joke aside, that looks like color reduction or something like that.
There is no reason it should happen but maybe your printer driver is special.Can you test with a normal mainwindow gui project and use this function
It will print whole window. Can you tell me if that also have strange colors issues?
Btw: What Qt version and platform?void MainWindow::printPage() { QPixmap pix = QPixmap::grabWindow(QApplication::desktop()->winId()); QPrinter printer(QPrinter::HighResolution); printer.setOrientation(QPrinter::Landscape); QPainter painter; painter.begin(&printer); double xscale = printer.pageRect().width() / double(pix.width()); double yscale = printer.pageRect().height() / double(pix.height()); double scale = qMin(xscale, yscale); painter.translate(printer.paperRect().x() + printer.pageRect().width() / 2, printer.paperRect().y() + printer.pageRect().height() / 2); painter.scale(scale, scale); painter.translate(-width() / 2, -height() / 2); painter.drawPixmap(0, 0, pix); painter.end(); }
Also, is there a chance your printer is a CMYK printer?
That would explain it as Qt uses RGB and Scribus is clever enough to
convert from RGB to CMYK on printing. -
Hello,
I am on Qt 5.7 and currently running on windows 7.
Yes, the printer is a CMYK printer (it uses a CMYK + overlay ribbon). I had a lot of doubts about this being the issue. Is there any way around this ? Maybe converting the rgb values to CMYK within the RGBA container ?
I'll try your sample code on the side as well, but I have a feeling I'll get the same result.
Thanks,
BasiC
-
Tried your code. It's harder to distinguish because of how small it is (and the background is white), but I do believe there is still some color issues.
I'll admit it doesn't look as bad, but maybe that's because colors don't blend as much as a picture would.
Edit: Confirmed with a different background.
Thanks,
BasiC
-
@BasiC
Good test!
So it indeed printing RGB image to printer that causes issues.
Sometimes its possible to ask printer to convert from RGB to CMYK colorspace.
Else i think you must convert the image.
Only way i have seen its via pixel manipulation.
If this is for home use, you could also just use imagemagick and call it from QProcess.
That could convert and adjust the image anyway you want. -
Hi,
I've been looking all over for some documentation about asking the printer to perform the conversion, but it didn't look promising with my printer.
About pixel manipulation, you mean that I would need to modify the data buffer itself or I could, in some way, fool Qt into thinking it is RGBA if I set it right ? Do you have some examples ?
I'll take a look into ImageMagick...
Thanks,
BasiC
-
Hi
Only something like this
http://stackoverflow.com/questions/27949569/convert-a-qimage-to-grayscale
https://www.programmingalgorithms.com/algorithm/rgb-to-cmyk?lang=C%2B%2B
QColor also has CMYK support. -
Hello again,
I did figure that QColor supported CMYK, but I am unsure as to how I should put it all together back in the image. Once I get a QColor object from the QColor::toCMYK() call, the only way I can replace the pixel inside the QImage is through QColor::rgba, which returns actual RGBA values. However, I now remember that I had not opened the file explicitly in RGBA format at the time. I will attempt this again and see what I can come up with.
I'll keep you updated.
Thanks,
BasiC
-
Hi back,
I tried something like this :
studentPicture.convertToFormat(QImage::Format_RGBA8888); for(int j = 0; j < studentPicture.height(); j++) { for(int i = 0; i < studentPicture.width(); i++) { int c = 0, m = 0, y = 0, k = 0; QColor oldColor = studentPicture.pixel(i, j); oldColor = oldColor.toCmyk(); oldColor.getCmyk(&c, &m, &y, &k); QColor newColor(c, m , y, k); studentPicture.setPixel(i, j, newColor.rgba()); } }
However, the result doesn't look promising at all... Do you have any more pointer for me ?
Thanks,
BasiC
-
Hi wb
Does look like I would expect.
But you still have massive color
I wonder if .setPixel(i, j, newColor.rgba() << will that convert back to RGB? );http://doc.qt.io/qt-5/qimage.html#setPixelColor-1
It seems to accept a QColor directly so maybe it can get rid of the .rgb() ?Sadly I have not tested this with Cmyk - only greyscale and other manipulations so
im not sure why its not working.Also, i would install ImageMagick and make a Cmyk version and print it. just be sure it will work and
you have a Cmyk version to compare with.
Since Scribus can print nicely I assume 99.9% its due to Qt sending image as RGB. -
Good morning,
Removing .rgba() doesn't compile. I need to head to work, but I'll try printing with a CMYK converted image too as soon as I can.
Thanks,
BasiC
-
Hi,
I tried printing the CMYK output and it still looked bad, but I'm guessing Qt might be converting it to rgb when it loads it ?
Thanks
-
@BasiC
Yes, i would assume it does.
Im not sure how to bypass that.After removing rgb() did you use
http://doc.qt.io/qt-5/qimage.html#setPixelColor-1
Note its not setPixel, but set PixelColor and it accpet a "pure" color? -
@mrjj
You caught me off guard with the added Color in method name. I'll try it out as soon as I get a minute. -
Tried the code. I only exported to PDF for testing purposes and I believe it wouldn't print properly...
By the way, this looks a little like when I was using .rgba().
-
@BasiC
Well its pretty hard to look at CMYK images on RGB monitor and know if they be all right :)
PDF might convert to RGB as in adobe its default . Dont know if Qt export is.
You could ask Adobe Reader to save as cmyk to be sure. ( if you have it)Maybe its not possible to do in Qt directly as setPixelColor does accept Color CMYK version
so it should have worked. Also the images you load are JPGS ? (png not good for cmyk i read)I think it still get convert to RGB or something. that all other pixel manipulation works.
Maybe its needed to construct raw buffer and handle all loading and saving by own code.Also if you did install imagemagick
try
convert image-rgb.jpg -colorspace CMYK image-cmyk.jpg
and print from windows -
Thanks for the reply. I'm in a little rush currently. Hopefully I can test your pointers out pretty soon.