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

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')

Related

Get Geometry of widgets with variable size

Situation
I have a pop_up widget (say a textbox), which I can place arbitrarily on the screen by setting the properties x and y accordingly.
On the other hand I use the prompt, which is located in the default wibar.
I would like to place the pop_up widget directly below the prompt
Problem
I was not yet able to gather any useful information about the geometry of the prompt. With geometry I mean its x and y values together with its height and width. I solved the y-positioning by using the height of the wibar itself.
But I am stuck with x-positioning.
Is there a way to get the width of the widgets within the toolbar?
Notice
I read something about forced_width, but in this situation it sounds like a hack to me. So I would prefer to avoid forcing any widths.
I'm currently running awesome WM 4.2 on Fedora 26
Part of a problem is that "a" widget does not have a position and size since awesome allows widgets to be shown in multiple places at once. However, if we just ignore this problem, something like the following could work (to be honest: I did not test this):
function find_widget_in_wibox(wb, widget)
local function find_widget_in_hierarchy(h, widget)
if h:get_widget() == widget then
return h
end
local result
for _, ch in ipairs(h:get_children()) do
result = result or find_widget_in_hierarchy(ch, widget)
end
return result
end
local h = wb._drawable._widget_hierarchy
return h and find_widget_in_hierarchy(h, widget)
end
However, I have to warn you that the above could break in newer versions of awesome since it access non-public API (the part with wb._drawable._widget_hierarchy). There is a way to work with just the public API using :find_widgets(), but I am too lazy for that for now.
The above function gets the wibox.hierarchy instance representing a widget which allows to get the geometry of the prompt via something like the following (in the default config of awesome 4.2):
local s = screen.primary -- Pick a screen to work with
local h = find_widget_in_wibox(s.mywibox, s.mypromptbox)
local x, y, width, height = h:get_matrix_to_device()
:transform_rectangle(0, 0, h:get_size())
local geo = s.mywibox:geometry()
x, y = x + geo.x, y + geo.y
print(string.format("The widget is inside of the rectangle (%d, %d, %d, %d) on the screen", x, y, width, height)
Finally, note that the widget hierarchy is only updated during repaints. So, during startup the code above will fail to find the widget at all and right after something changed (e.g. you entered another character into the promptbox), the above will still "figure out" the old geometry.

Windows Small System Icon Height Incorrect

I'm running on Windows 10, but using Delphi 7 (yes, I know it's quite old).
I want to use the system icons in Windows and have gone about this by defining a TImageList called SystemIcons which I initialize as follows:
var
fileInfo: TSHFileInfo;
begin
SystemIcons.Handle := ShGetFileInfo('', 0, fileInfo, SizeOf(fileInfo),
SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SYSICONINDEX);
...
I have SystemIcons properties set statically as a TImageList component with width and height set to 16.
Elsewhere, I wish to retrieve an icon from this image list given a valid shell object's image index. Because these are "small system icons", I expect them to be 16x16. The result of calling GetSystemMetrics(SM_CYSMICON) yields 16. Oddly, the dimensions depend upon whether I retrieve them as a bitmap or an icon.
...
var
icon: TIcon;
bm: TBitmap;
begin
...
icon := TIcon.Create;
SystemIcons.GetIcon(imgIndex, icon);
bm := TBitmap.Create;
SystemIcons.GetBitmap(imgIndex, bm);
The imgIndex is correct and the same in both cases. The image retrieved is the same in each case, as expected. The dimensions of the bitmap (bm.Width and bm.Height) are also as expected: 16x16. However, the dimensions of the icon (icon.Width and icon.Height) are not. They are 32x32.
When I paint the icon on a canvas it appears as 16x16. So it's only its Height and Width values that appear incorrect. Very odd.
Why are these different?
The images are likely actually 32x32 to begin with.
Internally, TImageList.GetIcon() simply retrieves an HICON for the chosen image directly from the underlying Win32 ImageList API, using ImageList_GetIcon(), and assigns that to the TIcon.Handle property.
TImageList.GetBitmap(), on the other hand, is a bit different. It sizes the TBitmap to the dimensions of the TImageList (16x16), and then stretch draws the chosen image onto the TBitmap.Canvas using TImageList.Draw(), which in turn uses ImageList_DrawEx().

Why does my OBJ / MTL model material show up as black?

Why does my OBJ model have has no material and display as black?
I have an OBJ:
<a-obj-model id="gorilla" src="#gorilla-obj" mtl="#gorilla-mtl"></a-obj-model>
I can see the geometry, but the material shows up as black.
If you check your MTL, you might notice it is trying to use TGA or some other sort of textures that aren't plain images. In this case, you need to include additional three.js loaders.
You could try including all the necessary loaders like including https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/TGALoader.js and THREE.Loader.Handlers.add( /\.tga$/i, new THREE.TGALoader() );
However, it might be simplest to just batch convert all the TGAs to just use images like PNGs using a converter, and replace all instances of 'tga' with 'png'.

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.

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

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);

Resources