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