Forum > Graphics

Different TBitmap.RawImage.Data behavior in Win32 and Linux

(1/6) > >>

dan59314:
Hi,

  I tried to manipulate TBitmap.RawImage.Data as following, load a bmp file, copy to a new TBitmap, and save to a new file. But get different result in Win32 and Linux.

  With the same source code....

--- Code: ---procedure TForm1.Button1Click(Sender: TObject);
var
  bmp1, bmp2:TBitmap;
  ptr1, ptr2:Pointer;
  i:integer;
begin

  //if OpenDialog1.Execute then
  begin
    try
      bmp1:=TBitmap.Create;
      bmp2:=TBitmap.Create;

      bmp1.LoadFromFile('test.bmp'); //OpenDialog1.FileName);
      bmp2.PixelFormat := bmp1.PixelFormat;
      bmp2.Width := bmp1.Width;
      bmp2.Height := bmp1.Height;

      for i:=0 to bmp1.Height-1 do
      begin
        ptr1 := bmp1.RawImage.Data + bmp1.Width*3*i;
        ptr2 := bmp2.RawImage.Data+ bmp2.Width*3*i;

        Move(ptr1^, ptr2^, bmp1.Width*3);
      end;

      bmp2.SaveToFile('aa.bmp');

    finally
      bmp1.Free;
      bmp2.Free;
    end;
  end;

end;
--- End code ---

Got different result, 
   
   In Windows http://dan59314.myweb.hinet.net/WindowsImage.jpg

   In Linux http://dan59314.myweb.hinet.net/LinuxImage.jpg

   How to fix the problem? Is it a bug?

Thanks,

Regards,

Daniel

Marc:

--- Code: ---ptr1 := bmp1.RawImage.Data + bmp1.Width*3*i;

--- End code ---

the problems here are the assumptions you make:
  Each pixel will take 3 bytes and each row is byte alligned
This is complete platform dependent, look at the rawimage.description how the data is layout in memory

dan59314:

--- Quote from: Marc on October 27, 2009, 10:38:58 am ---
--- Code: ---ptr1 := bmp1.RawImage.Data + bmp1.Width*3*i;

--- End code ---

the problems here are the assumptions you make:
  Each pixel will take 3 bytes and each row is byte alligned
This is complete platform dependent, look at the rawimage.description how the data is layout in memory

--- End quote ---

Hi, Marc,

  Thanks again.

  Yes, I loaded the 24bit bmp file, size 480x360, 3 bytes per pixel, I guess the stridebytes should be bmp.Width*3 = 480*3 = 1440.   

  I search and found in GraphType.pp the TRawImageDescription, still don't know how the linux align the raw data.

  Then I google 'Linux Raw Data format', 'Linux Raw Data mainpulate'.., can't find any hint can make the code work.

   Then I wondered that may works if I add  'bmp2.RawImage.Description := bmp1.RawImage.Description;' after set bmp2 size. But still the same.

   Didn't tried it out yet.

  May you revise the code and show me how to make it works the same result in both linux and windows?



Regards,

Daniel

 

Vincent Snijders:
You must use the bmp1.RawImage.Description fields to determine how to copy the bytes. See http://lazarus-ccr.sourceforge.net/docs/lcl/graphtype/trawimagedescription.html for a explanation of the fields.

In your copying code you assume  BitsPerPixel=24 and  LineEnd=rileByteBoundary. Is that true?

dan59314:

--- Quote from: Vincent Snijders on October 28, 2009, 08:58:35 am ---You must use the bmp1.RawImage.Description fields to determine how to copy the bytes. See http://lazarus-ccr.sourceforge.net/docs/lcl/graphtype/trawimagedescription.html for a explanation of the fields.

In your copying code you assume  BitsPerPixel=24 and  LineEnd=rileByteBoundary. Is that true?

--- End quote ---

Thanks,

  I read the explanation, and assign 3 fields.

      bmp2.RawImage.Description.Format:=  ricfRGBA;                                                 
      bmp2.RawImage.Description.BitsPerPixel:=BitsPerPixel;                                         
      bmp2.RawImage.Description.LineEnd:=rileDWordBoundary;                   


--- Code: ---                                                                                     
function BytesPerScanline(PixelsPerScanline, BitsPerPixel,                                         
  Alignment: Integer): Longint;                                                                     
begin                                                                                               
  Dec(Alignment);                                                                                   
  Result := ((PixelsPerScanline * BitsPerPixel) + Alignment) and not Alignment;                     
  Result := Result div 8;                                                                           
end;                                                                                           
procedure TForm1.Button1Click(Sender: TObject);                                                     
var                                                                                                 
  bmp1, bmp2:TBitmap;                                                                               
  ptr1, ptr2, p0:Pointer;                                                                           
  i,j,strideBytes,BYtesPerPixel,BitsPerPixel:integer;                                               
begin                                                                                       
  //if OpenDialog1.Execute then                                                                     
  begin                                                                                             
    try                                                                                             
      bmp1:=TBitmap.Create;                                                                         
      bmp2:=TBitmap.Create;                                                     
      bmp1.LoadFromFile('test.bmp'); //OpenDialog1.FileName);                                       
      bmp2.PixelFormat := bmp1.PixelFormat;                                                         
      bmp2.Width := bmp1.Width;                                                                     
      bmp2.Height := bmp1.Height;                                           
      BitsPerPixel :=24;                                                                           
      bmp2.RawImage.Description.Format:=  ricfRGBA;                                                 
      bmp2.RawImage.Description.BitsPerPixel:=BitsPerPixel;                                         
      bmp2.RawImage.Description.LineEnd:=rileDWordBoundary;               
      strideBytes := BytesPerScanline(bmp1.Width, BitsPerPixel, 32);                               
      BytesPerPixel := BitsPerPixel div 8;                                                 
      //bmp2.RawImage.Description := bmp1.RawImage.Description;         
      for i:=0 to bmp1.Height-1 do                                                                 
      begin                                                                                         
        ptr1 := bmp1.RawImage.Data+strideBytes*i;                                                   
        ptr2 := bmp2.RawImage.Data+strideBytes*i;                 
        Move(ptr1^, ptr2^, strideBytes);                                                           
      end;                                                                     
      bmp2.SaveToFile('aa.bmp');                                               
    finally                                                                                         
      bmp1.Free;                                                                                   
      bmp2.Free;                                                                                   
    end;                                                                                           
  end;                                                                                         
end;                                                                                               

--- End code ---


  In Windows, I guess it's 32 bits aligned, means rileDWordBoundary.  I suppose Linux also the same.

 if I assign the
      bmp2.RawImage.Description := bmp1.RawImage.Description;   
  and
      copy the RawImage data with the for loop, increasing pointer.

  The bmp2 should be as same as bmp1, isn't it?


   BTW, in Windows, the Raw Image aligned in   BGRBGRBGRBGR........
 
   Is the Linux aligned in a different manner?  EX   BBBBBBBBBBBBB.....  GGGGGGGG.... RRRRRR...,   first Blue data block, then the Green, the Red... ? ( Because the image seems have multiple shifted image.)

Thanks,

Regards,

Daniel

Navigation

[0] Message Index

[#] Next page

Go to full version