使用FireMonkey delphi Xe3创建固定在32bits像素格式的屏幕屏幕图的替代方案



由于FMX TBITMAP实现具有PixelFormat为仅读取属性,因此我无法像以前那样使用VCL TBITMAP来创建一个空的TBITMAP之后,将其设置为32bits。此示例显示了如何使用fmx rutines getpixel,setPixel:http://members.adug.org.au/2012/101/10/10/05/read-write-image-image-image-bitmap-pixels-/

使用fmx tbitmap.map()方法,我可以访问指向像素数据的指针,但是我不能假设其PixelforMat至32位。

我的目的是以32位的固定格式访问32bits位图,纹理或表面,以便我的2D图形库可以直接与该内存一起在屏幕上工作;无需在像素格式之间进行检查和转换。在图像处理的末尾,它可以复制到任何可见的表面,纹理或图像,以显示形式。

帮助您感谢!

要解决位图的扫描线的像素,您可以使用属性tbitmap.scanlines [0],它为您提供了指向图像的第一行的指针。要了解扫描线是如何用24个位图构造的,您可以看到David Heffernan和Tlama的文章:

如何将扫描线属性用于24位位图?

我已经创建了在Delphi下运行的汇编编程语言函数,并允许您从/到32位/Pixel位映像读取/编写像素(而24位/Pixel位图)。

这是我的getPixelBmp32()和putpixelbmp32()函数的原型和功能:

type T_RGB_Temp=record {RGB color RECORD type}
      Blue, {BLUE component from 0 to 255}
      Green, {GREEN component from 0 to 255}
      Red, {RED component from 0 to 255}
      Mask {ALPHA channel from 0 to 255} :byte;
     end;
     T_Coord_XY=record {X and Y position RECORD type}
      X, {X position}
      Y {Y position} :smallint;
     end;
     T_Dim_XY=record {Width and height of bitmap RECORD type}
      DimX, {Width}
      DimY {Height} :word;
     end;
function GetPixelBMp32(XY:T_Coord_XY;
                       BMp32_Dim_XY:T_Dim_XY;
                       ScanLine0:pointer):T_RGB_Temp;
procedure PutPixelBMp32(XY:T_Coord_XY;
                        BMp32_Dim_XY:T_Dim_XY;
                        ScanLine0:pointer;Pix:T_RGB_Temp);

给定的bitmap32:用pixelformat =(pf32bit,pfcustom)定义的tbitmap,scanline0参数必须始终为bitmap32.scanline [0];如果scanline0 = nil,什么也不会发生。

bmp32_dim_xy.dimx和bmp32_dim_xy.dimy是给定图像的尺寸;如果您使用类型cast bmp32_dim_xy.dimx:= word(width:smallInt)或bmp32_dim_xy.dimx:= word(height:smallInt),宽度或高度是负面的。

xy.x和xy.y是像素的坐标;它们可能是负面的或大于给定图像的大小,但是在这种情况下,什么都没有发生。

pix.red,pix.green,pix.blue,pix.mask是像素的8位颜色组件。pix是T_RGB_TEMP类型;GetPixelBmp32()的结果也是相同类型的。

位图的扫描线的组织是相反的,就好像记忆中的图像相对于x轴镜像;因此

此外,如果扫描线的字节数不是4的倍数(与dword的对齐),如24位/像素格式中,则在扫描线的末端添加0到3个字节(对齐)(对齐)。

计算24个位图的对齐方式是通过:a::=(tbitmap.width 3)而不是3。

以下是上述函数的定义(32位/像素图像):

procedure PutPixelBMp32(XY:T_Coord_XY;
                        BMp32_Dim_XY:T_Dim_XY;
                        ScanLine0:pointer;Pix:T_RGB_Temp); assembler;
{ eax edx ecx are 1°, 2° and 3° parameters.
  Can freely modify the eax, ecx, and edx registers. }
asm
     push  ebx
     push  esi
     push  edi
     mov   ebx,Pix        {ebx <- Pix}
     mov   edi,BMp32_Dim_XY {edi <- edx <- BMp32_Dim_XY}
     mov   esi,ScanLine0  {esi <- ecx <- ScanLine0}
     mov   edx,XY         {edx <- eax <- XY}
     or    esi,esi        {If ScanLine0=Nil, ...}
     je    @@00           {... Exit}
     movsx eax,di         {eax <- DimX}
     shr   edi,16
     movsx edi,di         {edi <- DimY}
     movsx ecx,dx         {ecx <- X}
     shr   edx,16
     movsx edx,dx         {edx <- Y}
     or    eax,eax        {If DimX<0, ...}
     js    @@00           {... Exit}
     cmp   ecx,eax        {If X<0 or if X>=DimX, ...}
     jae   @@00           {... Exit}
     or    edi,edi        {If DimY<0, ...}
     js    @@00           {... Exit}
     cmp   edx,edi        {If Y<0 or if Y>=DimY, ...}
     jae   @@00           {... Exit}
     lea   ecx,[4*ecx]    {ecx <- X position in byte}
     lea   esi,[esi+ecx]  {Update source pointer and free ecx}
     lea   eax,[4*eax]    {eax <- scanline size in byte}
     mul   edx            {eax <- Y * (scanline size in byte)}
     sub   esi,eax        {esi <- Pixel write target pointer}
     mov   [esi],ebx      {bl <- Blue; bh <- Green; byte2(ebx) <- Red; byte3(ebx) <- Mask}
@@00:pop   edi
     pop   esi
     pop   ebx
end;
function GetPixelBMp32(XY:T_Coord_XY;
                       BMp32_Dim_XY:T_Dim_XY;
                       ScanLine0:pointer):T_RGB_Temp; assembler;
{ eax edx ecx are 1°, 2° and 3° parameters.
  Can freely modify the eax, ecx, and edx registers. }
asm
     push  esi
     push  edi
     mov   edi,BMp32_Dim_XY {edi <- edx <- BMp32_Dim_XY}
     mov   esi,ScanLine0  {esi <- ecx <- ScanLine0}
     mov   edx,XY         {edx <- eax <- XY}
     xor   eax,eax        {Inizializza @Result a 0}
     or    esi,esi        {If ScanLine0=Nil, ...}
     je    @@00           {... Exit}
     movsx eax,di         {eax <- DimX}
     shr   edi,16
     movsx edi,di         {edi <- DimY}
     movsx ecx,dx         {ecx <- X}
     shr   edx,16
     movsx edx,dx         {edx <- Y}
     or    eax,eax        {If DimX<0, ...}
     js    @@00           {... Exit}
     cmp   ecx,eax        {If X<0 or if X>=DimX, ...}
     jae   @@00           {... Exit}
     or    edi,edi        {If DimY<0, ...}
     js    @@00           {... Exit}
     cmp   edx,edi        {If Y<0 or if Y>=DimY, ...}
     jae   @@00           {... Exit}
     lea   ecx,[4*ecx]    {ecx <- X position in byte}
     lea   esi,[esi+ecx]  {Update source pointer and free ecx}
     lea   eax,[4*eax]    {eax <- scanline size in byte}
     mul   edx            {eax <- Y * (scanline size in byte)}
     sub   esi,eax        {esi <- Pixel write target pointer}
     mov   eax,[esi]      {al <- Blue; ah <- Green; byte2(eax) <- Red; byte3(eax) <- Mask}
@@00:pop   edi
     pop   esi
end;

以下是已经定义了参数类型的函数的定义(24位/像素图像):

procedure PutPixelBMp24(XY:T_Coord_XY;
                        BMp24_Dim_XY:T_Dim_XY;
                        ScanLine0:pointer;Pix:T_RGB_Temp); assembler;
{ eax edx ecx are 1°, 2° and 3° parameters.
  Can freely modify the eax, ecx, and edx registers. }
asm
     push  ebx
     push  esi
     push  edi
     mov   ebx,Pix        {ebx <- Pix}
     mov   edi,BMp24_Dim_XY {edi <- edx <- BMp24_Dim_XY}
     mov   esi,ScanLine0  {esi <- ecx <- ScanLine0}
     mov   edx,XY         {edx <- eax <- XY}
     or    esi,esi        {If ScanLine0=Nil, ...}
     je    @@00           {... Exit}
     movsx eax,di         {eax <- DimX}
     shr   edi,16
     movsx edi,di         {edi <- DimY}
     movsx ecx,dx         {ecx <- X}
     shr   edx,16
     movsx edx,dx         {edx <- Y}
     or    eax,eax        {If DimX<0, ...}
     js    @@00           {... Exit}
     cmp   ecx,eax        {If X<0 or if X>=DimX, ...}
     jae   @@00           {... Exit}
     or    edi,edi        {If DimY<0, ...}
     js    @@00           {... Exit}
     cmp   edx,edi        {If Y<0 or if Y>=DimY, ...}
     jae   @@00           {... Exit}
     lea   ecx,[ecx+2*ecx]{ecx <- X position in byte}
     lea   esi,[esi+ecx]  {Update source pointer and free ecx}
     lea   eax,[eax+2*eax]{eax <- scanline size in byte}
     add   eax,3          {Process in eax ...}
     and   eax,0FFFFFFFCH {... The dword aligned scanline size in byte}
     mul   edx            {eax <- Y * (dword aligned scanline size in byte)}
     sub   esi,eax        {esi <- Pixel write target pointer}
     mov   [esi],bx       {bl <- Blue; bh <- Green}
     shr   ebx,8          {bh <- Red}
     mov   [esi+2],bh     {bh <- Red}
@@00:pop   edi
     pop   esi
     pop   ebx
end;
function GetPixelBMp24(XY:T_Coord_XY;
                       BMp24_Dim_XY:T_Dim_XY;
                       ScanLine0:pointer):T_RGB_Temp; assembler;
{ eax edx ecx are 1°, 2° and 3° parameters.
  Can freely modify the eax, ecx, and edx registers. }
asm
     push  esi
     push  edi
     mov   edi,BMp24_Dim_XY {edi <- edx <- BMp24_Dim_XY}
     mov   esi,ScanLine0  {esi <- ecx <- ScanLine0}
     mov   edx,XY         {edx <- eax <- XY}
     xor   eax,eax        {Inizializza @Result a 0}
     or    esi,esi        {If ScanLine0=Nil, ...}
     je    @@00           {... Exit}
     movsx eax,di         {eax <- DimX}
     shr   edi,16
     movsx edi,di         {edi <- DimY}
     movsx ecx,dx         {ecx <- X}
     shr   edx,16
     movsx edx,dx         {edx <- Y}
     or    eax,eax        {If DimX<0, ...}
     js    @@00           {... Exit}
     cmp   ecx,eax        {If X<0 or if X>=DimX, ...}
     jae   @@00           {... Exit}
     or    edi,edi        {If DimY<0, ...}
     js    @@00           {... Exit}
     cmp   edx,edi        {If Y<0 or if Y>=DimY, ...}
     jae   @@00           {... Exit}
     lea   ecx,[ecx+2*ecx]{ecx <- X position in byte}
     lea   esi,[esi+ecx]  {Update source pointer and free ecx}
     lea   eax,[eax+2*eax]{eax <- scanline size in byte}
     add   eax,3          {Process in eax ...}
     and   eax,0FFFFFFFCH {... The dword aligned scanline size in byte}
     mul   edx            {eax <- Y * (dword aligned scanline size in byte)}
     sub   esi,eax        {esi <- Pixel write target pointer}
     mov   ax,[esi+1]     {al -> Green; ah -> Red}
     shl   eax,8          {B2 -> Red; B1 -> Green}
     mov   al,[esi]       {B0 -> Blue}
@@00:pop   edi
     pop   esi
end;

如果您需要更高的传输速度,则是简化版本,但没有检查传入参数的正确性,getPixelBmp32()和putpixelbmp32()函数:

procedure PutPixelBMp32(XY:T_Coord_XY;
                        BMp24_Dim_XY:T_Dim_XY;
                        ScanLine0:pointer;Pix:T_RGB_Temp); assembler;
{ eax edx ecx are 1°, 2° and 3° parameters.
  Can freely modify the eax, ecx, and edx registers. }
asm
     push  ebx
     push  esi
     mov   ebx,Pix        {ebx <- Pix}
     mov   esi,ScanLine0  {esi <- ecx <- ScanLine0}
     mov   eax,XY         {eax <- eax <- XY}
     mov   edx,BMp32_Dim_XY {edx <- edx <- BMp32_Dim_XY}
     movzx edx,dx         {edx <- DimX}
     movzx ecx,ax         {ecx <- X}
     shr   eax,16
     movzx eax,ax         {eax <- Y}
     lea   ecx,[4*ecx]    {ecx <- X position in byte}
     lea   esi,[esi+ecx]  {Update source pointer and free ecx}
     lea   edx,[4*edx]    {edx <- scanline size in byte}
     mul   edx            {eax <- Y * (scanline size in byte)}
     sub   esi,eax        {esi <- Pixel write target pointer}
     mov   [esi],ebx      {bl <- Blue; bh <- Green; byte2(ebx) <- Red; byte3(ebx) <- Mask}
     pop   esi
     pop   ebx
end;
function GetPixelBMp32(XY:T_Coord_XY;
                       BMp24_Dim_XY:T_Dim_XY;
                       ScanLine0:pointer):T_RGB_Temp; assembler;
{ eax edx ecx are 1°, 2° and 3° parameters.
  Can freely modify the eax, ecx, and edx registers. }
asm
     push  esi
     mov   esi,ScanLine0  {esi <- ecx <- ScanLine0}
     mov   eax,XY         {eax <- eax <- XY}
     mov   edx,BMp32_Dim_XY {edx <- edx <- BMp32_Dim_XY}
     movzx edx,dx         {edx <- DimX}
     movzx ecx,ax         {ecx <- X}
     shr   eax,16
     movzx eax,ax         {eax <- Y}
     lea   ecx,[4*ecx]    {ecx <- X position in byte}
     lea   esi,[esi+ecx]  {Update source pointer and free ecx}
     lea   edx,[4*edx]    {edx <- scanline size in byte}
     mul   edx            {edx <- Y * (scanline size in byte)}
     sub   esi,eax        {esi <- Pixel write target pointer}
     mov   eax,[esi]      {al <- Blue; ah <- Green; byte2(eax) <- Red; byte3(eax) <- Mask}
     pop   esi
end;

相关内容

  • 没有找到相关文章

最新更新