mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-10 03:35:58 +02:00
Starts screenshot taking code in LCL-CustomDrawn-Cocoa, already works, but the colors are switched
git-svn-id: trunk@34268 -
This commit is contained in:
parent
2a70b1b482
commit
d2c89a1ff3
@ -239,7 +239,7 @@ begin
|
||||
javaEnvRef^^.CallVoidMethod(javaEnvRef, javaActivityObject, javaMethod_LCLDoShowMessageBox);
|
||||
end;
|
||||
|
||||
(*{------------------------------------------------------------------------------
|
||||
{------------------------------------------------------------------------------
|
||||
Function: RawImage_FromDevice
|
||||
Params: ADC:
|
||||
ARect:
|
||||
@ -255,27 +255,9 @@ end;
|
||||
So get this internal bitmap and pass it to RawImage_FromBitmap
|
||||
------------------------------------------------------------------------------}
|
||||
function TQtWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
|
||||
var
|
||||
Desc: TRawImageDescription absolute ARawImage.Description;
|
||||
|
||||
//SrcWidth, SrcHeight: Integer;
|
||||
WinID: Cardinal;
|
||||
DCSize: TSize;
|
||||
Pixmap: TQtPixmap;
|
||||
Image: QImageH;
|
||||
Context: TQtDeviceContext;
|
||||
|
||||
procedure RawImage_FromImage(AImage: QImageH);
|
||||
begin
|
||||
ARawImage.DataSize := QImage_numBytes(AImage);
|
||||
ARawImage.Data := GetMem(ARawImage.DataSize);
|
||||
Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize);
|
||||
ARawImage.Mask := nil;
|
||||
end;
|
||||
|
||||
begin
|
||||
{$ifdef VerboseQtWinAPI}
|
||||
WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
|
||||
{$ifdef VerboseCDWinAPI}
|
||||
DebugLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
|
||||
' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
|
||||
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
|
||||
{$endif}
|
||||
@ -285,56 +267,7 @@ begin
|
||||
Result := True;
|
||||
|
||||
ARawImage.Init;
|
||||
FillStandardDescription(ARawImage.Description);
|
||||
Context := TQtDeviceContext(ADC);
|
||||
|
||||
with DCSize, Context.getDeviceSize do
|
||||
begin
|
||||
cx := x;
|
||||
cy := y;
|
||||
end;
|
||||
|
||||
if Context.Parent <> nil then
|
||||
begin
|
||||
Pixmap := TQtPixmap.Create(@DCSize);
|
||||
WinID := QWidget_winId(Context.Parent);
|
||||
try
|
||||
// if you have dual monitors then getDeviceSize return
|
||||
// more width than screen width, but grabWindow will only grab one
|
||||
// screen, so its width will be less
|
||||
// Solution: we can either pass prefered size to grabWindow or
|
||||
// correct Description size after. I see the first solution as more correct.
|
||||
Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy);
|
||||
Image := QImage_Create;
|
||||
Pixmap.toImage(Image);
|
||||
RawImage_FromImage(Image);
|
||||
QImage_destroy(Image);
|
||||
finally
|
||||
Pixmap.Free;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
if Context.vImage <> nil then
|
||||
RawImage_FromImage(Context.vImage.FHandle)
|
||||
else
|
||||
if Context.ParentPixmap <> nil then
|
||||
begin
|
||||
Image := QImage_create();
|
||||
QPixmap_toImage(Context.ParentPixmap, Image);
|
||||
RawImage_FromImage(Image);
|
||||
QImage_destroy(Image);
|
||||
end else
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
// In this case we use the size of the context
|
||||
Desc.Width := DCSize.cx;
|
||||
Desc.Height := DCSize.cy;
|
||||
|
||||
{$ifdef VerboseQtWinAPI}
|
||||
WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
|
||||
{$endif}
|
||||
end;*)
|
||||
end;
|
||||
|
||||
procedure TCDWidgetSet.ShowVirtualKeyboard;
|
||||
begin
|
||||
|
@ -128,7 +128,7 @@ function TCDWidgetSet.PromptUser(const DialogCaption : string;
|
||||
begin
|
||||
end;
|
||||
|
||||
(*{------------------------------------------------------------------------------
|
||||
{------------------------------------------------------------------------------
|
||||
Function: RawImage_FromDevice
|
||||
Params: ADC:
|
||||
ARect:
|
||||
@ -142,88 +142,64 @@ end;
|
||||
|
||||
MWE: exept for the desktop, there is always a bitmep selected in the DC.
|
||||
So get this internal bitmap and pass it to RawImage_FromBitmap
|
||||
|
||||
Reference documentation:
|
||||
|
||||
Technical Q&A QA1509 Getting the pixel data from a CGImage object
|
||||
http://developer.apple.com/library/mac/#qa/qa1509/_index.html
|
||||
|
||||
CGDisplayCreateImage
|
||||
http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/Quartz_Services_Ref/Reference/reference.html
|
||||
|
||||
http://lists.apple.com/archives/cocoa-dev/2011/Feb/msg00704.html
|
||||
|
||||
CFDataRef
|
||||
http://developer.apple.com/library/ios/#DOCUMENTATION/CoreFoundation/Reference/CFDataRef/Reference/reference.html
|
||||
------------------------------------------------------------------------------}
|
||||
function TQtWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
|
||||
function TCDWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
|
||||
var
|
||||
Desc: TRawImageDescription absolute ARawImage.Description;
|
||||
|
||||
//SrcWidth, SrcHeight: Integer;
|
||||
WinID: Cardinal;
|
||||
DCSize: TSize;
|
||||
Pixmap: TQtPixmap;
|
||||
Image: QImageH;
|
||||
Context: TQtDeviceContext;
|
||||
|
||||
procedure RawImage_FromImage(AImage: QImageH);
|
||||
begin
|
||||
ARawImage.DataSize := QImage_numBytes(AImage);
|
||||
ARawImage.Data := GetMem(ARawImage.DataSize);
|
||||
Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize);
|
||||
ARawImage.Mask := nil;
|
||||
end;
|
||||
|
||||
screenshotImage: CGImageRef;
|
||||
imageDataProv: CGDataProviderRef;
|
||||
imageData: CFDataRef;
|
||||
lBitsPerComponent, lBitsPerPixel, lBytesPerRow: size_t;
|
||||
lDataPtr: UnivPtr;
|
||||
lDataLength: CFIndex;
|
||||
begin
|
||||
{$ifdef VerboseQtWinAPI}
|
||||
WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
|
||||
' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
|
||||
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
|
||||
{$endif}
|
||||
|
||||
// todo: copy only passed rectangle
|
||||
|
||||
Result := True;
|
||||
|
||||
ARawImage.Init;
|
||||
FillStandardDescription(ARawImage.Description);
|
||||
Context := TQtDeviceContext(ADC);
|
||||
ARawImage.Description.Init_BPP32_B8G8R8A8_BIO_TTB(0, 0);
|
||||
|
||||
with DCSize, Context.getDeviceSize do
|
||||
begin
|
||||
cx := x;
|
||||
cy := y;
|
||||
end;
|
||||
// Take the screenshot and obtain the pixel data
|
||||
screenshotImage := CGDisplayCreateImage(CGMainDisplayID()); // Requires 10.6+
|
||||
imageDataProv := CGImageGetDataProvider(screenshotImage); // Requires 10.5+
|
||||
imageData := CGDataProviderCopyData(imageDataProv);
|
||||
|
||||
if Context.Parent <> nil then
|
||||
begin
|
||||
Pixmap := TQtPixmap.Create(@DCSize);
|
||||
WinID := QWidget_winId(Context.Parent);
|
||||
try
|
||||
// if you have dual monitors then getDeviceSize return
|
||||
// more width than screen width, but grabWindow will only grab one
|
||||
// screen, so its width will be less
|
||||
// Solution: we can either pass prefered size to grabWindow or
|
||||
// correct Description size after. I see the first solution as more correct.
|
||||
Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy);
|
||||
Image := QImage_Create;
|
||||
Pixmap.toImage(Image);
|
||||
RawImage_FromImage(Image);
|
||||
QImage_destroy(Image);
|
||||
finally
|
||||
Pixmap.Free;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
if Context.vImage <> nil then
|
||||
RawImage_FromImage(Context.vImage.FHandle)
|
||||
else
|
||||
if Context.ParentPixmap <> nil then
|
||||
begin
|
||||
Image := QImage_create();
|
||||
QPixmap_toImage(Context.ParentPixmap, Image);
|
||||
RawImage_FromImage(Image);
|
||||
QImage_destroy(Image);
|
||||
end else
|
||||
Result := False;
|
||||
end;
|
||||
// Now read the image description and convert it to our own
|
||||
lBitsPerComponent := CGImageGetBitsPerComponent(screenshotImage);
|
||||
ARawImage.Description.AlphaPrec := 0;
|
||||
ARawImage.Description.RedPrec := lBitsPerComponent;
|
||||
ARawImage.Description.GreenPrec := lBitsPerComponent;
|
||||
ARawImage.Description.BluePrec := lBitsPerComponent;
|
||||
ARawImage.Description.RedShift := 0;
|
||||
ARawImage.Description.GreenShift := 8;
|
||||
ARawImage.Description.BlueShift := 16;
|
||||
|
||||
// In this case we use the size of the context
|
||||
Desc.Width := DCSize.cx;
|
||||
Desc.Height := DCSize.cy;
|
||||
ARawImage.Description.Width := CGImageGetWidth(screenshotImage);
|
||||
ARawImage.Description.Height := CGImageGetHeight(screenshotImage);
|
||||
|
||||
{$ifdef VerboseQtWinAPI}
|
||||
WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
|
||||
{$endif}
|
||||
end;*)
|
||||
lBitsPerPixel := CGImageGetBitsPerPixel(screenshotImage); // For now support it will give us 32
|
||||
|
||||
lBytesPerRow := CGImageGetBytesPerRow(screenshotImage);
|
||||
|
||||
// Now copy the data
|
||||
lDataPtr := CFDataGetBytePtr(imageData);
|
||||
lDataLength := CFDataGetLength(imageData);
|
||||
ARawImage.CreateData(False);
|
||||
lDataLength := Min(lDataLength, ARawImage.DataSize);
|
||||
System.Move(lDataPtr^, ARawImage.Data^, lDataLength);
|
||||
end;
|
||||
|
||||
procedure TCDWidgetset.ShowVirtualKeyboard();
|
||||
begin
|
||||
|
@ -129,7 +129,7 @@ function TCDWidgetSet.PromptUser(const DialogCaption : string;
|
||||
begin
|
||||
end;
|
||||
|
||||
(*{------------------------------------------------------------------------------
|
||||
{------------------------------------------------------------------------------
|
||||
Function: RawImage_FromDevice
|
||||
Params: ADC:
|
||||
ARect:
|
||||
@ -144,87 +144,12 @@ end;
|
||||
MWE: exept for the desktop, there is always a bitmep selected in the DC.
|
||||
So get this internal bitmap and pass it to RawImage_FromBitmap
|
||||
------------------------------------------------------------------------------}
|
||||
function TQtWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
|
||||
var
|
||||
Desc: TRawImageDescription absolute ARawImage.Description;
|
||||
|
||||
//SrcWidth, SrcHeight: Integer;
|
||||
WinID: Cardinal;
|
||||
DCSize: TSize;
|
||||
Pixmap: TQtPixmap;
|
||||
Image: QImageH;
|
||||
Context: TQtDeviceContext;
|
||||
|
||||
procedure RawImage_FromImage(AImage: QImageH);
|
||||
begin
|
||||
ARawImage.DataSize := QImage_numBytes(AImage);
|
||||
ARawImage.Data := GetMem(ARawImage.DataSize);
|
||||
Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize);
|
||||
ARawImage.Mask := nil;
|
||||
end;
|
||||
|
||||
function TCDWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
|
||||
begin
|
||||
{$ifdef VerboseQtWinAPI}
|
||||
WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
|
||||
' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
|
||||
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
|
||||
{$endif}
|
||||
|
||||
// todo: copy only passed rectangle
|
||||
|
||||
Result := True;
|
||||
|
||||
ARawImage.Init;
|
||||
FillStandardDescription(ARawImage.Description);
|
||||
Context := TQtDeviceContext(ADC);
|
||||
|
||||
with DCSize, Context.getDeviceSize do
|
||||
begin
|
||||
cx := x;
|
||||
cy := y;
|
||||
end;
|
||||
|
||||
if Context.Parent <> nil then
|
||||
begin
|
||||
Pixmap := TQtPixmap.Create(@DCSize);
|
||||
WinID := QWidget_winId(Context.Parent);
|
||||
try
|
||||
// if you have dual monitors then getDeviceSize return
|
||||
// more width than screen width, but grabWindow will only grab one
|
||||
// screen, so its width will be less
|
||||
// Solution: we can either pass prefered size to grabWindow or
|
||||
// correct Description size after. I see the first solution as more correct.
|
||||
Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy);
|
||||
Image := QImage_Create;
|
||||
Pixmap.toImage(Image);
|
||||
RawImage_FromImage(Image);
|
||||
QImage_destroy(Image);
|
||||
finally
|
||||
Pixmap.Free;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
if Context.vImage <> nil then
|
||||
RawImage_FromImage(Context.vImage.FHandle)
|
||||
else
|
||||
if Context.ParentPixmap <> nil then
|
||||
begin
|
||||
Image := QImage_create();
|
||||
QPixmap_toImage(Context.ParentPixmap, Image);
|
||||
RawImage_FromImage(Image);
|
||||
QImage_destroy(Image);
|
||||
end else
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
// In this case we use the size of the context
|
||||
Desc.Width := DCSize.cx;
|
||||
Desc.Height := DCSize.cy;
|
||||
|
||||
{$ifdef VerboseQtWinAPI}
|
||||
WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
|
||||
{$endif}
|
||||
end;*)
|
||||
end;
|
||||
|
||||
procedure TCDWidgetset.ShowVirtualKeyboard();
|
||||
begin
|
||||
|
@ -129,7 +129,7 @@ function TCDWidgetSet.PromptUser(const DialogCaption : string;
|
||||
begin
|
||||
end;
|
||||
|
||||
(*{------------------------------------------------------------------------------
|
||||
{------------------------------------------------------------------------------
|
||||
Function: RawImage_FromDevice
|
||||
Params: ADC:
|
||||
ARect:
|
||||
@ -145,27 +145,9 @@ end;
|
||||
So get this internal bitmap and pass it to RawImage_FromBitmap
|
||||
------------------------------------------------------------------------------}
|
||||
function TCDWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
|
||||
var
|
||||
Desc: TRawImageDescription absolute ARawImage.Description;
|
||||
|
||||
//SrcWidth, SrcHeight: Integer;
|
||||
WinID: Cardinal;
|
||||
DCSize: TSize;
|
||||
Pixmap: TQtPixmap;
|
||||
Image: QImageH;
|
||||
Context: TQtDeviceContext;
|
||||
|
||||
procedure RawImage_FromImage(AImage: QImageH);
|
||||
begin
|
||||
ARawImage.DataSize := QImage_numBytes(AImage);
|
||||
ARawImage.Data := GetMem(ARawImage.DataSize);
|
||||
Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize);
|
||||
ARawImage.Mask := nil;
|
||||
end;
|
||||
|
||||
begin
|
||||
{$ifdef VerboseQtWinAPI}
|
||||
WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
|
||||
{$ifdef VerboseCDWinAPI}
|
||||
DebugLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
|
||||
' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
|
||||
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
|
||||
{$endif}
|
||||
@ -175,56 +157,7 @@ begin
|
||||
Result := True;
|
||||
|
||||
ARawImage.Init;
|
||||
FillStandardDescription(ARawImage.Description);
|
||||
Context := TQtDeviceContext(ADC);
|
||||
|
||||
with DCSize, Context.getDeviceSize do
|
||||
begin
|
||||
cx := x;
|
||||
cy := y;
|
||||
end;
|
||||
|
||||
if Context.Parent <> nil then
|
||||
begin
|
||||
Pixmap := TQtPixmap.Create(@DCSize);
|
||||
WinID := QWidget_winId(Context.Parent);
|
||||
try
|
||||
// if you have dual monitors then getDeviceSize return
|
||||
// more width than screen width, but grabWindow will only grab one
|
||||
// screen, so its width will be less
|
||||
// Solution: we can either pass prefered size to grabWindow or
|
||||
// correct Description size after. I see the first solution as more correct.
|
||||
Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy);
|
||||
Image := QImage_Create;
|
||||
Pixmap.toImage(Image);
|
||||
RawImage_FromImage(Image);
|
||||
QImage_destroy(Image);
|
||||
finally
|
||||
Pixmap.Free;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
if Context.vImage <> nil then
|
||||
RawImage_FromImage(Context.vImage.FHandle)
|
||||
else
|
||||
if Context.ParentPixmap <> nil then
|
||||
begin
|
||||
Image := QImage_create();
|
||||
QPixmap_toImage(Context.ParentPixmap, Image);
|
||||
RawImage_FromImage(Image);
|
||||
QImage_destroy(Image);
|
||||
end else
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
// In this case we use the size of the context
|
||||
Desc.Width := DCSize.cx;
|
||||
Desc.Height := DCSize.cy;
|
||||
|
||||
{$ifdef VerboseQtWinAPI}
|
||||
WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
|
||||
{$endif}
|
||||
end;*)
|
||||
end;
|
||||
|
||||
procedure TCDWidgetset.ShowVirtualKeyboard();
|
||||
begin
|
||||
|
@ -67,7 +67,7 @@ function RawImage_DescriptionFromBitmap(ABitmap: HBITMAP; out ADesc: TRawImageDe
|
||||
function RawImage_DescriptionFromDevice(ADC: HDC; out ADesc: TRawImageDescription): Boolean; override;
|
||||
|
||||
function RawImage_FromBitmap(out ARawImage: TRawImage; ABitmap, AMask: HBITMAP; ARect: PRect = nil): Boolean; override;
|
||||
//function RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; override;
|
||||
function RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; override;
|
||||
function RawImage_QueryDescription(AFlags: TRawImageQueryFlags; var ADesc: TRawImageDescription): Boolean; override;
|
||||
(*function ReleaseDesignerDC(Window: HWND; DC: HDC): Integer; override;
|
||||
|
||||
|
@ -114,7 +114,7 @@ end;"/>
|
||||
<License Value="modified LGPL-2
|
||||
"/>
|
||||
<Version Major="1" Release="1"/>
|
||||
<Files Count="384">
|
||||
<Files Count="388">
|
||||
<Item1>
|
||||
<Filename Value="carbon/agl.pp"/>
|
||||
<AddToUsesPkgSection Value="False"/>
|
||||
@ -1908,6 +1908,22 @@ end;"/>
|
||||
<AddToUsesPkgSection Value="False"/>
|
||||
<UnitName Value="customdrawnprivate"/>
|
||||
</Item384>
|
||||
<Item385>
|
||||
<Filename Value="customdrawn/customdrawnlclintf_android.inc"/>
|
||||
<Type Value="Include"/>
|
||||
</Item385>
|
||||
<Item386>
|
||||
<Filename Value="customdrawn/customdrawnlclintf_cocoa.inc"/>
|
||||
<Type Value="Include"/>
|
||||
</Item386>
|
||||
<Item387>
|
||||
<Filename Value="customdrawn/customdrawnlclintf_win.inc"/>
|
||||
<Type Value="Include"/>
|
||||
</Item387>
|
||||
<Item388>
|
||||
<Filename Value="customdrawn/customdrawnlclintf_x11.inc"/>
|
||||
<Type Value="Include"/>
|
||||
</Item388>
|
||||
</Files>
|
||||
<LazDoc Paths="../../docs/xml/lcl"/>
|
||||
<i18n>
|
||||
|
Loading…
Reference in New Issue
Block a user