2013-10-06 4 views
2

이 코드는 웹에서 발견되었지만 FMX.Bitmap에는 스캔 라인이 없습니다. VCL.TBitmap을 FMX.Bitmap에 복사하거나 그릴 수 있습니까?VCL.Bitmap To FMX.Bitmap

{$IFDEF MSWINDOWS} 
type 
    TBitmap = FMX.Types.TBitmap; 
    TVclBitmap = Vcl.Graphics.TBitmap; 

procedure TakeScreenshot(Dest: FMX.Types.TBitmap); 
var 
    DC: HDC; 
    Size: TPointF; 
    VCLBitmap: TVclBitmap; 
    Y: Integer; 
begin 
    VCLBitmap := nil; 
    //Size := FMX.Platform.IFMXScreenService.GetScreenSize; 
    DC := GetDC(0); 
    try 
    VCLBitmap := TVclBitmap.Create; 
    VCLBitmap.PixelFormat := pf32bit; 
    VCLBitmap.SetSize(Trunc(Size.X), Trunc(Size.Y)); 
    BitBlt(VCLBitmap.Canvas.Handle, 0, 0, VCLBitmap.Width, VCLBitmap.Height, 
     DC, 0, 0, SRCCOPY); 
    Dest.SetSize(VCLBitmap.Width, VCLBitmap.Height); 
    { The format of a FMX bitmap and a 32 bit VCL bitmap is the same, so just 
     copy the scanlines. - not true- FMX bitmap does not have ScanLine? } 
    for Y := Dest.Height - 1 downto 0 do 
     Move(VCLBitmap.ScanLine[Y]^, Dest.ScanLine[Y]^, Dest.Width * 4); 
    {Dest.Canvas.DrawBitmap(); Not possible to assign or draw} 
    finally 
    ReleaseDC(0, DC); 
    VCLBitmap.Free; 
    end; 
end; 
{$ENDIF} 
+0

을 원래의 코드와 주석 (https://delphi-foundations.googlecode.com/svn/trunk/XE2%20book/13의 저자로. % 20Native % 20APIs/% 20a % 20screenshot/ScreenshotForm.pas), 나는 FMX TBitmap이 원래 ScanLine 속성을 가지고 있다고 말할 수 있습니다. 그러나 이것은 XE3의 Map/Unmap 메소드로 추상화되었습니다. –

+0

@Chris ... 예 .. 당신의 코드입니다. 죄송합니다. 귀하를 언급하지 않았지만이 질문을 쓸 때 귀하의 웹 사이트를 찾을 수 없습니다. Map/Unmap을 사용하는 예가 있습니까? – Bill

+0

음 FMX TClipboard 코드 (http://code.google.com/p/delphi-foundations/source/browse/trunk/FMX%20Utilities/CCR.FMXClipboard.Win.pas - TWinClipboard.DoAssignBitmap 참조)에서 사용합니다. . 나중에 스크린 샷 코드를 업데이트 할 것입니다 (블로그 게시물을 가져올 것입니다). –

답변

5

당신은 스트림을 사용할 수 있습니다

{$IFDEF MSWINDOWS} 

type 

    TVclBitmap = Vcl.Graphics.TBitmap; 

procedure TakeScreenshot(Dest: TBitmap); 
var 
    DC: HDC; 
    Size: TPointF; 
    VCLBitmap: TVclBitmap; 
    Y: Integer; 
    MS: TMemoryStream; 
begin 
    MS := TMemoryStream.Create; 
    VCLBitmap := nil; 
    // Size := FMX.Platform.IFMXScreenService.GetScreenSize; 
    DC := GetDC(0); 
    Size.X := 500; 
    Size.Y := 500; 
    try 
    VCLBitmap := TVclBitmap.Create; 
    VCLBitmap.PixelFormat := pf32bit; 
    VCLBitmap.SetSize(Trunc(Size.X), Trunc(Size.Y)); 
    BitBlt(VCLBitmap.Canvas.Handle, 0, 0, VCLBitmap.Width, VCLBitmap.Height, DC, 
     0, 0, SRCCOPY); 
    Dest.SetSize(VCLBitmap.Width, VCLBitmap.Height); 
    { The format of a FMX bitmap and a 32 bit VCL bitmap is the same, so just 
     copy the scanlines. - not true- FMX bitmap does not have ScanLine? } 
    VCLBitmap.SaveToStream(MS); 
    MS.Position := 0; 
    Dest.LoadFromStream(MS); 
    MS.Free; 
    { Dest.Canvas.DrawBitmap(); Not possible to assign or draw } 
    finally 
    ReleaseDC(0, DC); 
    VCLBitmap.Free; 
    end; 
end; 
{$ENDIF} 
+0

@ S.MAHDI - 고마워요 ... – Bill

+4

누출되지 않도록 MS를 보호해야합니다. –

+0

이것은 매우 느립니다. (매우!) Map을 사용하여 FMX 비트 맵의 ​​픽셀 데이터에 액세스하고 Scanline을 사용하여 VCL 비트 맵의 ​​픽셀 데이터에 액세스하고 픽셀을 직접 복사/변환 할 수 있습니다. –