Strange problem about conversion between GDI+ to GDI: Bitmap and HBitmap - gdi+

I want to convert gdi+ Bitmap into gdi object HBitmap.
I am using the following method:
Bitmap* img = new Bitmap(XXX);
// lots of codes...
HBITMAP temp;
Color color;
img->GetHBITMAP(color, &temp);
the img object is drawing on a dialog.
when this part of method is called, strange thing happens!
the img displaying in the window changed!
It become a bit clearer or sharper.
My question is what happens?

The bitmap pixel format may be the reason. Do you specify it explicitly in the Bitmap constructor?
Gdiplus::Bitmap bmp(WIDTH, HEIGHT, PixelFormat24bppRGB);
Try making sure that all the pixel formats you use are the same.
Another reason may be the differences in Gdiplus::Graphics interpolation modes in your code. That attribute determines how the images are resized, how the lines are drawn, etc.
m_pViewPortImage = new Gdiplus::Bitmap(
observedWidth,
observedHeight,
PixelFormat24bppRGB
);
Gdiplus::Graphics gr(m_pViewPortImage);
gr.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic);

Related

Is it possible to set a clip path on a QImage or save what a Qpainter paints?

I have a QImage I am able to clip out a QRegion of and successfully clip out the region using the QPainter class setClipRegion() function. However, I want to save what is drawn as a new QImage but am not seeing anything in the docs about saving what is actually displayed.
I've tried directly changing the images alpha channel to match the clipping region but my implementation is very inefficient. The setClipRegion() function was the only thing I learned that could efficiently display what I wanted. My end goal is to use the clipped image as a QOpenGLTexture so I somehow need to save the originally clipped image.
Thanks for any help.
You can simply specify a new file name when saving. so you do not overwrite the old one.
image = QtGui.QImage('orginal.png')
output = QtGui.QImage(image.size(), QtGui.QImage.Format_ARGB32)
output.fill(QtCore.Qt.transparent)
painter = QtGui.QPainter(output)
....
-> your clip path
....
painter.drawImage(QtCore.QPoint(), image)
painter.end()
output.save('new.png')

Load and Save opaque 8 bit PNG Files using ImageSharp

I am trying to Load -> Manipulate byte array directly -> Save an 8 bit png image.
I would like to use ImageSharp to compare its speeds to my current library, however in their code example they require the pixel type to be defined (they use Rgba32):
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
// Image.Load(string path) is a shortcut for our default type.
// Other pixel formats use Image.Load<TPixel>(string path))
using (Image<Rgba32> image = Image.Load("foo.jpg"))
{
image.Mutate(x => x
.Resize(image.Width / 2, image.Height / 2)
.Grayscale());
image.Save("bar.jpg"); // Automatic encoder selected based on extension.
}
I looked through the pixel types: https://github.com/SixLabors/ImageSharp/tree/master/src/ImageSharp/PixelFormats
But there is no grayscale 8 bit pixel type.
As of 1.0.0-beta0005 There's no Gray8 pixel format because we couldn't decide what color model to use when converting from Rgb (We need that internally). ITU-R Recommendation BT.709 seems like the sensible solution because that is what png supports and what we use when saving an image as an 8bit grayscale png so it's on my TODO list.
https://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
So... currently you need to use either Rgb24 or Rgba32 when decoding the images.
Update.
As of 1.0.0-dev002094 this is now possible! We have two new pixel formats. Gray8 and Gray16 that carry only the luminance component of a pixel.
using (Image<Gray8> image = Image.Load<Gray8>("foo.png"))
{
image.Mutate(x => x
.Resize(image.Width / 2, image.Height / 2));
image.Save("bar.png");
}
Note. The png encoder by default will save the image in the input color type and bit depth. If you want to encode the image in a different color type you will need to new up an PngEncoder instance with the ColorType and BitDepth properties set.

Qt-Application is killing characters accidentally (drawText produces bug)

I've got a really simple application for adding watermarks to pictures. So you can drop your pictures in a QListWidget which shows you a thumbnail and the path, adjust some things like the text, the transparency, the output format and so on.. and after pressing start it saves the copyrighted picture in a destination of your choice. This works with a QPainter which paints the logo and text on the picture.
Everything is able to work fine. But here's the misterious bug:
The application kills random letters. It's really strange, because I can't reproduce it. With every execution and combination of options it's different. For example:
Sometimes I can't write some letters in the QLineEdit of my interface (like E, 4 and 0 doesnt exist, or he changes the letters so some special signs).
The text of the items in the QListWidget aren't completly displayed, sometimes completley missing. But I can extract the text normally and use the path.
While execution I have a QTextBrowser as a log to display some interesting things like the font size. Although, the font is shown normaly on the resulting picture, it says " 4" or "6" instead of much higher and correct sizes. Betimes strange white blocks appear between some letters
When drawing text on the picture with a QPainter, there also letters missing. Sometimes, all the letters are printed over each other. It seems like this bug appears more often when using small pixelsizes (like 12):
//Text//
int fontSize = (watermarkHeight-(4*frame));
int fontX = 2*frame;
int fontY = (result.height()-(watermarkHeight-2*frame));
int fontWidth = watermarkWidth;
QRect place(fontX,fontY,fontWidth,fontSize);
QFont font("Helvetica Neue", QFont::Light);
font.setPixelSize(fontSize);
emit log(QString::number(fontSize));
pixPaint.setFont(font);
pixPaint.setPen(QColor(255,255,255,textOpacity));
pixPaint.drawText(place,text);
Not all of these bugs appear at once! Sometimes I haven't got any bugs...
Perhaps someone had a similar bug before. Unfortunately I didn't found something like this in the internet. I didn't post a lot of code snippets because I think (and hope) that this is a gerneral problem. If you need something specific to help me, please let me know =)
I've added a example picture:
In the lineEdit I simply wrote ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 (look what he has done with the 7 and 9)
This small square in the lower corner of the picture should be the "ABC..." thing
The "62" looks very strange in the textBrowser
I'm using Qt 5.0.1 on a Windows 7 64Bit computer.
EDIT: Everytime after adding the first picture to the list, he's finding these warnings:
QFontEngine::loadEngine: GetTextMetrics failed ()
QWindowsFontEngine: GetTextMetrics failed ()
But when I change the height (and with it the pointSize of the font) its not emitted anymore, even with the start-parameters.
EDIT 2: Thank you for your help! I corrected my code so that he only uses correct fonts and correct sizes, but it still doesn't work. When I remove the QPainter::drawText() function it works fine (without the text). But as soon as I am adding text everything is bugged. I have something like this now:
//Text//
QList<int> smoothSizes = fontDatabase->smoothSizes("Verdana","Standard");
int fontSize = (watermarkHeight-(4*frame))*0.75;
emit log("Requested: "+QString::number(fontSize));
if(!smoothSizes.contains(fontSize)){
for(int i = 0; i<smoothSizes.length(); i++){
if(smoothSizes.at(i) > fontSize && i>0){
fontSize = smoothSizes.at(i-1);
break;
}
}
}
int fontX = 2*frame;
int fontY = (result.height()-(watermarkHeight/2)+frame);
QFont font = fontDatabase->font("Verdana","Standard",fontSize);
QFontInfo info(font);
emit log("Corrected: "+QString::number(fontSize));
emit log("Okay?: "+QString::number(info.exactMatch()));
pixPaint.setFont(font);
const QFontMetrics fontMetrics = pixPaint.fontMetrics();
if(info.exactMatch()){
pixPaint.setPen(QColor(255,255,255,textOpacity));
pixPaint.drawText(fontX,fontY+(fontMetrics.height()-fontMetrics.ascent()),text);
}
It almost sounds like you are corrupting random memory in your process, or you have a badly broken Windows install. Possibly your font request is matched by a very poorly chosen system font.
Whatever is set on a QFont is merely a request. To obtain the parameters of the actual font that was selected, you must create a QFontInfo, and get your information from there.
Imagine that you request a QFont that doesn't exist on a system, or that can't be scaled to a particular size. At some point the font object would need to morph to reflect what really happened - this would be very confusing. Thus, the QFontInfo provides the information about the font that was actually used. Think of QFontInfo as a response, and QFont as a request.
I finally found a solution: I simply updated Qt from 5.0.1 to 5.2.1, now it works. Perhaps someone has a similar bug and this post helps him. Thank you for your help!

Qt-GUI Testing with Squish or other stuff

Is there a way to find out the filename of a QPixmap? My intention was to test which pixmap is currently set.
I've tried Squish to find out any properties, but I've get only access to some stuff like width, height etc
I assume that while you writing a test you already know which image you want to see. You can convert QPixmap to QImage and check if it contains the same image as expected:
bool same = QImage(filename) == pixmap.toImage();
It's not efficient but should be ok for testing purposes.

Flex - How does nativeApplication.icon work?

NativeApplication.nativeApplication.icon.bitmaps = bitmapData();
I'm trying to edit the bitmaps for the system tray icon, but I got an error:
Implicit coercion of a value of type flash.display:BitmapData to an unrelated type Array.
What mistake did I make, or could you tell me the meaning of this error?
Icon.bitmaps is an Array of BitmapData, with one BitmapData instance for each size. You must reassign the entire array:
NativeApplication.nativeApplication.icon.bitmaps = new Array(bitmapData);
Alternatively, as the livedocs mention, you can specify all the bitmap sizes:
NativeApplication.nativeApplication.icon.bitmaps =
new Array(icon16x16.bitmapData, icon128x128.bitmapData);
I think you need a typecast in there such as:
SystemTrayIcon(NativeApplication.nativeApplication.icon).bitmaps
The SystemTrayIcon is a Windows-specific class I believe.
This is the discussion about this topic from Adobe:
http://livedocs.adobe.com/flex/3/html/help.html?content=taskbar_1.html

Resources