Optimizing Pixel Color Setting in Xojo Without Using RawBitmap Plugin

I am currently working on a project where I need to set the pixel colors of an image in Xojo. I am using a C shared library to set the RGB colors and then generating a Picture object in Xojo. My current approach involves creating a MemoryBlock and setting the colors pixel by pixel, which seems to be inefficient. Here is a snippet of my code:

Declare Function set_image_pixel_colors Lib "libTerraDll.dll" (image As Ptr, data As Ptr, tileframeimportant As Ptr, width As UInt32, height As UInt32, worldsurface As UInt32, rocklayer As UInt32) As Integer

Dim tileframeimportant As New MemoryBlock(World.Format.Tileframeimportant.Ubound + 1)

For i As Integer = 0 To World.Format.Tileframeimportant.Ubound
  tileframeimportant.UInt8Value(i) = World.Format.Tileframeimportant(i)
Next

Dim tileframeimportant_ptr As Ptr = tileframeimportant
Dim width As UInt32 = World.Width
Dim height As UInt32 = World.Height

Dim ImageSize As Integer = width * height * 3
Dim ImageMemory As MemoryBlock = New MemoryBlock(ImageSize)
Dim image As Ptr = ImageMemory
Dim data As Ptr = World.TileData
Dim worldsurface As UInt32 = World.Header.Worldsurface
Dim rocklayer As UInt32 = World.Header.Rocklayer

Dim result As Integer = set_image_pixel_colors(image, data, tileframeimportant_ptr, width, height, worldsurface, rocklayer)


Dim img As Picture = New Picture(width, height) 
Dim surface As Graphics = img.Graphics // 获取RGBSurface对象

Dim offset As Integer = 0
For y As Integer = 0 To height - 1
  For x As Integer = 0 To width - 1
    Dim red As Integer = image.UInt8(offset)
    Dim green As Integer = image.UInt8(offset + 1)
    Dim blue As Integer = image.UInt8(offset + 2)
    surface.Pixel(x, y) = Color.RGB(red,green,blue)
    offset = offset + 3
  Next
Next

I am aware of the RawBitmap plugin that could potentially optimize this process. However, I would prefer not to use this plugin and am looking for alternative solutions within the standard Xojo environment.
Could anyone suggest a more efficient way to set the pixel colors of an image in Xojo without using the RawBitmap plugin? Any advice or guidance would be greatly appreciated.
Thank you in advance for your help.

I think it would be helpful if you would describe what you’re trying to accomplish here. The code is clean but there might be subtleties that we’d miss by reading it.

1 Like

Yes, I forgot to add that.

I don’t think you’ll be able to match the performance of Einhuger RawBitmap or MBS PictureMBS in pure Xojo code.

There are a couple of things that might help though:
1.Use the Pragmas (stack overflow checking etc…) to speed up processing of the loops.

2.Pre-calculate width-1 and height-1 as they are getting calculated on each iteration.

3.Try limiting the memoryblock access to a single int32 access and divide the result to get the RGB values.

4.Try accessing the memoryblock via a Ptr.

1 Like

I note you commented out rgbsurface… thats faster… any reason?

Also , instead of getting 3 values as bytes

  Dim red As Integer = image.UInt8(offset)
    Dim green As Integer = image.UInt8(offset + 1)
    Dim blue As Integer = image.UInt8(offset + 2)

why not treat the memoryblock as UINT32s, and get 4 bytes at a time?
(Unless your image file is 24bit instead of 32bit per pixel…?)

1 Like