2016-04-24 18 views
1

Как можно преобразовать FMX.Graphics.TBitmap в VCL.Graphics.TBitmap или Vcl.Imaging.PngImage.TPngImage?Как преобразовать FMX.Graphics.TBitmap в VCL.Graphics.TBitmap или Vcl.Imaging.PngImage.TPngImage?

У меня есть форма FMX и форма VCL в моем проекте.

+1

Я полагаю, что вы могли бы сэкономить на поток памяти, а затем загрузить. Но было бы более эффективно использовать «Карта» для получения данных растрового изображения, а затем заполнить новый бит-образ VCL таким образом. –

ответ

1

Благодаря David Heffernan и некоторому поиску Я написал следующие функции.

я первый придумал функцию, которая не поддерживает альфа

function ConvertFmxBitmapToVclBitmap(b:FMX.Graphics.TBitmap):Vcl.Graphics.TBitmap; 
var 
    data:FMX.Graphics.TBitmapData; 
    i,j:Integer; 
    AlphaColor:TAlphaColor; 
begin 
    Result:=VCL.Graphics.TBitmap.Create; 
    Result.SetSize(b.Width,b.Height); 
    if(b.Map(TMapAccess.Readwrite,data))then 
    try 
    for i := 0 to data.Height-1 do begin 
     for j := 0 to data.Width-1 do begin 
     AlphaColor:=data.GetPixel(i,j); 
     Result.Canvas.Pixels[i,j]:= 
      RGB(
      TAlphaColorRec(AlphaColor).R, 
      TAlphaColorRec(AlphaColor).G, 
      TAlphaColorRec(AlphaColor).B); 
     end; 
    end; 
    finally 
    b.Unmap(data); 
    end; 
end; 

, и я написал вторую функцию для преобразования FMX.Graphics.TBitmap в Vcl.Imaging.PngImage.TPngImage и поддерживает Alpha.

function ConvertFmxBitmapToPng(b:FMX.Graphics.TBitmap):Vcl.Imaging.PngImage.TPngImage; 
var 
    data:FMX.Graphics.TBitmapData; 
    i,j:Integer; 
    AlphaColor:TAlphaColor; 
    AlphaLine:VCL.Imaging.PngImage.pByteArray; 
begin 
    result:=TPngImage.CreateBlank(COLOR_RGBALPHA, 8, b.Width, b.Height);; 
    if(b.Map(TMapAccess.Readwrite,data))then 
    try 
    for i := 0 to data.Height-1 do begin 
     AlphaLine:=Result.AlphaScanline[i]; 
     for j := 0 to data.Width-1 do begin 
     AlphaColor:=data.GetPixel(j,i); 
     AlphaLine^[j]:=TAlphaColorRec(AlphaColor).A; 
     Result.Pixels[j,i]:= 
      RGB(
      TAlphaColorRec(AlphaColor).R, 
      TAlphaColorRec(AlphaColor).G, 
      TAlphaColorRec(AlphaColor).B); 
     end; 
    end; 
    finally 
    b.Unmap(data); 
    end; 
end; 
+0

Это крайне медленное наивное решение. Взгляните на https://delphi-foundations.googlecode.com/svn/trunk/XE2%20book/13.%20Native%20APIs/Taking%20a%20screenshot/ScreenshotForm.pas –

0

Исправление для работы с прямоугольными изображениями:

function 
    ConvertFmxBitmapToVclBitmap(b:FMX.Graphics.TBitmap):Vcl.Graphics.TBitmap; 
var 
    data:FMX.Graphics.TBitmapData; 
    i,j:Integer; 
    AlphaColor:TAlphaColor; 
begin 
    Result:=VCL.Graphics.TBitmap.Create; 
    Result.SetSize(b.Width,b.Height); 
    if(b.Map(TMapAccess.Readwrite,data))then 
    try 
    for i := 0 to data.Height-1 do begin 
     for j := 0 to data.Width-1 do begin 
     AlphaColor:=data.GetPixel(j,i); 
     Result.Canvas.Pixels[j,i]:= 
      RGB(
      TAlphaColorRec(AlphaColor).R, 
      TAlphaColorRec(AlphaColor).G, 
      TAlphaColorRec(AlphaColor).B); 
     end; 
    end; 
    finally 
    b.Unmap(data); 
    end; 
end; 
+1

По-английски, пожалуйста. –