How do I convert an image to a binary image in QT? - qt

I have a normal .jpeg-file that I want to convert to a binary file with only pure black and pure white colours. I have already managed to convert an image to grayscale with code in QT.
QPixmap original(fileName);
QImage rgb2Gray;
rgb2Gray = original.toImage().convertToFormat(QImage::Format_Grayscale8);
QPixmap grayScale = original.fromImage(rgb2Gray);
However, I want to convert this grayscale image to a binary image.
Does anyone have any tips on how to do this?

Related

QLabel overlay png over gif

I have a QLabel and I can set a gif to animate as qmovie or a png to show as qpixmap.
What I want to do is to animate the gif and put a png over it.
Both images have transparent background. The gif is animated "loading circle", png is a "check" icon.
The code below is displaying the last one only.
#define MOOD_RESULT ":/mood/mood_result.gif"
#define MOOD_SUCCESS ":/mood/mood_success.png"
ui->moodicon->setPixmap(QPixmap(MOOD_SUCCESS));
QMovie *movie = new QMovie(MOOD_RESULT);
ui->moodicon->setMovie(movie);
movie->start();
I hope a Qt guru can help me.
Thanks in advance
Here are workable ideas:
Combine the images manually by playing the movie one-by-one into a pixmap, then overpainting the static image, and setting the result on the label.
Derive from QLabel, overload paintEvent, and overpaint the static image after calling QLabel::paintEvent.
Overlay another label on top of the one with the movie.

Scale Image in QWidget for printing

I use the following code to print a complex widget with text and static images:
printer = QPrinter()
printer.setResolution(PRINTER_DPI)
painter = QPainter(printer)
painter.scale(SCALE, SCALE)
my_widget.render(painter)
painter.end()
Text looks nice after applying scale() but the pixmaps on the widget still look pixelated when printed. I tried using a higher resolution source image and setting scaledContents on QLabel but this didn't seem to help.
Any ideas how I can increase the image resolution for printing?
Edit: I'm still interested in an answer but in the meantime I worked around the issue by using QSvgWidget with an svg source image instead of QLabel.

Change color of transparent image in Qt

I have a transparent image (QImage) overlayed over a video in Qt. I want to change the color of the transparent image only on clicks of button. Can some one tell me how to do this?
Thank You.
This can be done in many ways. I suggest to use QPainter to create new image. If you set SourceIn composition mode, starting image's alpha channel will be applied to any drawing that you will do. You just need to fill image with desired color.
QPixmap source_image; // should be preserved in a class member variable
QRgb base_color; // desired image color
QPixmap new_image = source_image;
QPainter painter(&new_image);
painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
painter.fillRect(new_image.rect(), base_color);
painter.end();
ui->label->setPixmap(new_image); // showing result
Note that I use QPixmap instead of QImage because QPixmaps are more efficient to display (and possibly paint). If you for some reason still want to use QImage, this code will work with QImage without any changes (excluding the last line of course).
Source image:
Result:

Correct way to display a QImage with QGLWidget?

How do I display a QImage in a QGLWidget? Do I have to draw a rectangle and add a texture on it or there is a better fashion?
You can use overpainting to draw a QImage over the QGLWidget, but it would certainly be faster pushing the image data out to the GPU by using the image as a texture.

GDI+ DrawImage of a JPG with white background is not white

I am displaying a JPG in a C++ CWnd window using GDI+. The JPG has a pure white background, 0xffffff, but when displayed using graphics.DrawImage, the background is off-white with a mix of pixel colors such as 0xfff7f7, 0xf7fff7, 0xf7f7f7. Below is the code, I have tried various settings such as CompositingMode, SmoothingMode, etc. The image is not scaled.
The weird thing is that the background color is different depending on other non-white content in the image. If I make a simple all white JPG, then it works, or even a mostly white with just some black text. Comparison of images are shown below.
CClientDC dc(this);
Gdiplus::Graphics graphics(dc);
Gdiplus::Bitmap* bmp = Gdiplus::Bitmap::FromFile( L"c:\\test.jpg" );
graphics.SetInterpolationMode(Gdiplus::InterpolationModeHighQuality);
//graphics.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality);
graphics.SetCompositingQuality(Gdiplus::CompositingQualityDefault);
graphics.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
//graphics.SetSmoothingMode( Gdiplus::SmoothingMode::SmoothingModeDefault );
graphics.DrawImage(bmp, 0, 0, bmp->GetWidth(), bmp->GetHeight() );
Here I have text and some blending only on the left side of the image (no alphas, this is JPG) . Everything to the right is pure white. You can see the background is all grey.
Here I started removing the internal content (only on the left side). After a certain point the entire background starts displaying white. ???
It doesn't really matter which part of the image area I remove before it starts displaying white, as long as I remove a large portion of it. The same occurs for pngs.
Here is the original test.jpg image...
I am answering my question with the solution that I found. It seems that using graphics.DrawImage directly on the passed HDC has some issues in my case. If I use a memory DC for the initial drawing, then BitBlt it on the HDC, then it works.
I also had some problems with PNG and transparency. Using the solution below, I was able to solve this problem as well. My PNG was loaded from a stream using Bitmap::FromStream. The alpha channel was lost and I was trying different attempts using LockBits and re-creating the bitmap with PixelFormat32bppARGB, as well as Cloning. I was able to get something to work (after a lot of effort and extra code), but it still had the grey background problem that I asked here.
In my case, I have a known solid background color for the transparent areas. I used Bitmap.GetHBITMAP and passed the background color. The bitmap was then drawn on the memory DC first. Here I was able to solve both of my problems!
Gdiplus::Bitmap* bmp = Gdiplus::Bitmap::FromFile( L"c:\test.jpg" )
Gdiplus::Color backColor( 0xff, 0xff, 0xff );
HBITMAP hBmp;
bmp->GetHBITMAP( backColor, &hBmp );
CDC bitmapDC;
bitmapDC.CreateCompatibleDC(hdc); // pass original HDC for drawing
HBITMAP oldBmp = bitmapDC.SelectBitmap(hBitmap);
::BitBlt( hdc, x, y, cx, cy, bitmapDC.m_hDC, 0, 0, SRCCOPY );
bitmapDC.SelectBitmap(oldBmp);
DeleteObject( hBmp );
If anyone knows, I would be interested why this fixes the problem.
How did you confirm the JPG background is truly white? JPG implements compression that can vary the color of pixels. If there are mixed colors, then there can be certain types of blending and mixing that are part of that compression.
Can you show us the original image?

Resources