04-27-2025, 08:35 PM
(04-27-2025, 03:21 PM)madscijr Wrote: Hey all. I know _CLEARCOLOR can be used multiple times if you want more than one color transparent, but is there a way to -quickly- copy only pixels of a given color to another image? This would need to be fast, like for animation. I think a command like "_CLEARCOLOR ExceptColor~&" would be useful for this. Or do we just have to compare POINT for every pixel?
That is why it is recommended to use the _Mem commands. It is much faster than Point and PSet. However, you must watch the area that is read/written and take into account the type of image. An 8bit image uses the palette index number in the range 0 to 255 as information about the pixel color, so the size of one pixel of an 8bit image is equal to 1byte. (_Unsigned _Byte specifically).
While a 32bit image uses 4bytes in memory: (RGBA)
The following is an example - how to copy one color from one image to another FAST. I wrote a classic solution and then the same with _Mem.
Code: (Select All)
image1 = _NewImage(800, 600, 32)
image2 = _NewImage(800, 600, 32)
Repeat = 10
_Dest image1
Cls , _RGB32(255, 27, 0)
Line (100, 100)-(300, 300), _RGB32(250, 120, 100), BF
_Dest image2
Cls , _RGB32(100, 127, 169)
Line (600, 400)-(700, 550), _RGB32(255, 0, 100), BF
_Dest 0
Print "Two images created. Press any key for view first image..."
Sleep
Screen image1
Print "Press any key for view second image..."
Sleep
Screen image2
Print "Press any key for copying image 1 to image 2 using POINT..."
Sleep
'copy image1 to newhandle my
my = _CopyImage(image1, 32)
T = Timer
For r = 1 To Repeat
For x = 0 To 799
For y = 0 To 599
_Source image2 'read pixels from image2
_Dest my 'write pixels to my
If Point(x, y) = _RGB32(255, 0, 100) Then PSet (x, y), _RGB32(255, 0, 100)
Next y, x
Next
Screen my
Print "Done using POINT in"; Timer - T; "Press any key for the same operation using _MEM"
Sleep
Screen 0
_FreeImage my
my = _CopyImage(image1, 32)
T = Timer
Dim As _MEM m, n
Dim c As Long
Dim Search As _Unsigned Long
Search = _RGB32(255, 0, 100)
m = _MemImage(image2)
n = _MemImage(my)
For r = 1 To Repeat
c = 0
Do Until c = m.SIZE
If _MemGet(m, m.OFFSET + c, _Unsigned Long) = Search Then
_MemPut n, n.OFFSET + c, Search
End If
c = c + 4 'step is 4 byte in memory for 32 bit image
Loop
Next r
Screen my
Print "Done using MEM in: "; Timer - T
Note that I intentionally set the program to execute the action 10 times in a row to highlight the difference in speed between PSET/POINT vs _MemGet and _MemPut. In my case, the speed difference is 100x.
Furthermore, when processing graphics (and other data), if you want it really fast, use loops DO... LOOP, While...Wend - they are faster than For...Next. When it comes to copying a square memory area, there are even faster _MEM methods than writing 4 bytes at 1 step per loop.