Color or .Red .Green .Blue?

I am trying to optimize this method for speed.
The for loop is either writing 3 bytes to the memory block using .Red, .Green, .Blue or it is writing a Color to the Memoryblock.
I would have thought the the writing of the color to the memory block would be faster so I’ve exchanged it for .Pixel.
However the images look bogus afterwards .
Did I miss something? Is Offset the byte offset of the ‘color’ offset?

[code]Sub PictureToMemory(p as Picture, m as MemoryBlock)
dim r, c, off as integer

if m = nil then
m = new MemoryBlock(p.Width * p.Height * 3)
off = 0
else
off = m.Size
m.Size = m.size + p.Width * p.Height * 3
end if

for r=0 to p.Height-1
for c=0 to p.Width-1
m.ColorValue(off, 24) = p.RGBSurface.Pixel(c,r)
//m.UInt8Value(off) = p.RGBSurface.Pixel(c,r).Red
//m.UInt8Value(off+1) = p.RGBSurface.Pixel(c,r).Green
//m.UInt8Value(off+2) = p.RGBSurface.Pixel(c,r).Blue
off = off + 3
next
next
End Sub[/code]

Is Picture.GetData too slow?

Change to this

dim surface as RGBSurface = p.RGBSurface
for r=0 to p.Height-1
    for c=0 to p.Width-1
        m.ColorValue(off, 24) = surface.Pixel(c,r)

I got:

DebugBuild:
Original    362220.059
Edited      114820.999001

Compiled (32-bit):
Original    288949.835001
Edited      74452.499001

Compiled (64-bit):
Original    202134.112999
Edited      49613.154001

I was hoping picture getdata would eliminate the need for the loops.
But I’m not sure I get if I can rely on the internal structure of the Pictures memory block… for all I know internally it is 4 bits per pixel… and the packing order… not sure…

But I agree it ‘should’ be the fastest…

Yes, Picture.GetData ± 4x faster than my solution and ± 13x faster than your code.

I only want RGB values 24 bits packed… Get data seems to want to return png, tiff etc … I don’t know how to get just a packed RGB 2D Matrix of Colors using getData.

I don’t know, I have no idea. In my head, you will go through a circle if using Picture.GetData. Get picture object from MemoryBlock using Picture.FromData, and then get RGB value from Picture.RGBSurface.

Tiff format will give you a header, which you can parse and skip, then it will give the raw bytes.

With TIFF the image data can appear anywhere in the file, so don’t assume it will be in a certain place.

However I’m not able to share any code right now, not at puter.

The other way you can do it on the Mac is to create a CGBitmapContext and you give it a memory block to fill. Then when you draw into that context, you’ll pixel data in whatever order or bitsepth you like.

It looks like you want the RAW bitmap data. I think Xojo uses the Windows BMP format which has a 54 byte header. I think if you remove the header you will get the RAW bitmap data. I have an example of taking RAW bitmap data and creating a Windows BMP for Xojo to use. Perhaps it will help.

Public Function Convert2BMP(mb As MemoryBlock , width As Int32, height As Int32) as Picture
  //  the 54 bytes header with required information
  Dim RGBBitmap as MemoryBlock =  new MemoryBlock(mb.Size +54)
  
  RGBBitmap.Int16Value(0)=&h4D42
  RGBBitmap.Int32Value(2)=mb.Size
  RGBBitmap.Int16Value(6)=0
  RGBBitmap.Int16Value(8)=0
  RGBBitmap.Int32Value(10)=54 //header size
  RGBBitmap.UInt32Value(14)=40
  RGBBitmap.Int32Value(18)=width
  RGBBitmap.Int32Value(22)=height
  RGBBitmap.UInt16Value(26)=1
  RGBBitmap.UInt16Value(28)=32 //bit depth
  RGBBitmap.UInt32Value(30)=0 //zero for uncompressed images
  RGBBitmap.UInt32Value(34)=0 //Size of raw bitmap data can be zero for BI_RGB bitmaps
  RGBBitmap.UInt32Value(38)=0  // preferred resolution in pixels per meter zero for no perference
  RGBBitmap.UInt32Value(42)=0 // preferred resolution in pixels per meter zero for no perference
  RGBBitmap.UInt32Value(46)=0
  RGBBitmap.UInt32Value(50)=0
  
  RGBBitmap.StringValue(54,mb.Size)=mb.StringValue(0,mb.Size) 'imageData.LeftB(mb.Size)
  
  //make a Picture from Data
  Dim bmp as picture=new picture (width,height,32)
  bmp=bmp.FromData(RGBBitmap)
  return bmp
End Function