Canvas.getPixel is not fully covered in TQtWidgetSet.DCGetPixel
Original Reporter info from Mantis: mm7
-
Reporter name: Mark Malakanov
Original Reporter info from Mantis: mm7
- Reporter name: Mark Malakanov
Description:
TQtWidgetSet.DCGetPixel gets pixels only from bitmap backed TCanvas (in Qt they have vImage).
It is not the case if Canvas belongs to TForm or other screen backed component, that in QT have only Painter, do not have vImage.
For compatibility with Lazarus canvas I've added support of screen backed canvases.
Steps to reproduce:
Create a form from TForm.
Try to get a pixel of form.canvas.pixels[x,y].
It will return clNone always.
Additional information:
I propose to add getting a pixel color from screen window of QT widget.
file qtobject.inc
class TQtWidgetSet ...
...
FInGetPixel : boolean;
...
function TQtWidgetSet.DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor;
var
Color: QColorH=nil;
Widget: QWidgetH=nil;
Pixmap: QPixmapH=nil;
Image: QImageH=nil;
Painter: QPainterH=nil;
Rgb: QRgb=0;
WindId: longword=0;
begin
Result := clNone;
if not IsValidDC(CanvasHandle) then Exit;
if (TQtDeviceContext(CanvasHandle).vImage <> nil) then
begin
Color := QColor_create(QImage_pixel(TQtDeviceContext(CanvasHandle).vImage.Handle, X, Y));
Result := RGBToColor(QColor_red(Color), QColor_green(Color), QColor_blue(Color));
QColor_destroy(Color);
end
else if (TQtDeviceContext(CanvasHandle).Widget <> nil) then
begin
Widget := TQtDeviceContext(CanvasHandle).Parent; //Parent is actually QWidgetH, and Widget is QPainterH.
if (Widget = nil) then
raise Exception.CreateFmt('TQtDeviceContext(CanvasHandle) %u : does not have Widget',[PtrUInt(CanvasHandle)]);
if FInGetPixel then //to prevent recursive call (QPixmap_grabWidget -> Widget.paint -> DCGetPixel)*
raise Exception.CreateFmt('TQtWidgetSet.DCGetPixel called recursively, probably from Paint method of Widget %u.',[PtrUInt(Widget)]);
FInGetPixel := true;
try
Pixmap:= QPixmap_create(1,1);
Image := QImage_create(1,1, QImageFormat_ARGB32);
//QPixmap_grabWidget(Pixmap, Widget, X,Y, 1,1); //this calls Widget.paint directed to bitmap and gets gets pixels from it. Slower.
WindId:=QWidget_winId(Widget);
QPixmap_grabWindow(Pixmap, WindId ,X,Y,1,1); //this gets pixels from screen.
QPixmap_toImage(PixMap,Image);
Rgb := QImage_Pixel(Image, 0,0);
Color := QColor_create(Rgb);
Result := RGBToColor(QColor_red(Color), QColor_green(Color), QColor_blue(Color));
finally
if Pixmap <> nil then QPixmap_destroy(Pixmap); //It looks like Qt caches pixmap despite of destroy
if Image <> nil then QImage_destroy(Image);
if Color <> nil then QColor_destroy(Color);
FInGetPixel := false;
end;
end
else
begin
raise Exception.CreateFmt('TQtDeviceContext(CanvasHandle) %u : does not have vImage or Painter',[PtrUInt(CanvasHandle)]);
end;
end;
Mantis conversion info:
- Mantis ID: 29276
- OS: linux
- OS Build: 3.13
- Platform: amd64
- Version: 1.4.4
- Fixed in revision: 62840 (#b9799e15)