CatchRawImage

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

CatchRawImage

Post by wilbert »

Don't know if it has been requested before but I couldn't find it.

CatchRawImage(#Image, Width, Height, *RGBAPixelBuffer)

The command would create a 32 bit image from raw pixel data in RGBA format.
The advantage would be to have a fast and cross platform way of creating images from raw data.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: CatchRawImage

Post by netmaestro »

The idea seems good for sure. Where would these blocks of colorbits typically come from?
BERESHEIT
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: CatchRawImage

Post by wilbert »

It's mainly a question because of my interest in assembler.
When you want to decode an image format PureBasic doesn't support or want to generate some kind of pattern such a command would be useful.
This way you could create all pixel data in memory and create a PureBasic image out of it with one command.

Currently you would either have to use Plot() for each pixel which results in a lot of procedure calls or use DrawingBuffer().
The problem with DrawingBuffer() is that according to the help file it is possible to have an image that doesn't support memory access and even if it does, you have to take into account a lot of options (is the image RGBA or BGRA, is the y coordinate flipped or not, the pitch of the buffer).
To have a cross platform command that simply takes a continuous stream of pixel data in a format that is the same on all operating systems would solve those problems.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: CatchRawImage

Post by Danilo »

CatchRawImage(#Image, Width, Height, *RGBAPixelBuffer, #PB_Image_32bit)
CatchRawImage(#Image, Width, Height, *RGBPixelBuffer, #PB_Image_24bit)
CatchRawImage(#Image, Width, Height, *RGBPixelBuffer, #PB_Image_16bit)

:?:
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: CatchRawImage

Post by netmaestro »

32bit is pretty straightforward but when you add in the lower depths a problem crops up. For 32bit your w*h gives the size of the memory block but at 24bit, not so much. Image colorbits at a depth of 24 must be DWORD aligned, which means that for a 10*10 image you have 32 widthbytes * 10 lines of height which comes to 320, not 300. So that raises the question, is the padding already in there or is it not? For 24 bits you might need to pass a size with it.
BERESHEIT
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: CatchRawImage

Post by Danilo »

netmaestro wrote:Image colorbits at a depth of 24 must be DWORD aligned
Who said that? You can read byte data with PB on any supported platform.

10*10*32bit = 400 bytes (RGBA)
10*10*24bit = 300 bytes (RGB)
10*10*16bit = 200 bytes

Maybe it makes sense to specify

Code: Select all

  #PB_PixelFormat_15Bits     : 2 bytes per pixel 
  #PB_PixelFormat_16Bits     : 2 bytes per pixel
  #PB_PixelFormat_24Bits_RGB  : 3 bytes per pixel (RRGGBB)
  #PB_PixelFormat_24Bits_BGR  : 3 bytes per pixel (BBGGRR)
  #PB_PixelFormat_32Bits_RGBA : 4 bytes per pixel (RRGGBBAA)
  #PB_PixelFormat_32Bits_ARGB : 4 bytes per pixel (AARRGGBB)
  #PB_PixelFormat_32Bits_BGRA : 4 bytes per pixel (BBGGRRAA)
  #PB_PixelFormat_32Bits_ABGR : 4 bytes per pixel (AABBGGRR)
but that could also be fixed to a specific PB-intern cross-platform format.
It is just raw pixel data, so you can draw sprites/images directly within data sections (like we did on C64 20 years ago):

Code: Select all

Data.l $FFFFFFFF, $FF00FFFF, $00FF00FF
CatchRawImage() + CatchRawSprite().
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: CatchRawImage

Post by netmaestro »

Code: Select all

CreateImage(0,10,10,24)
SaveImage(0, GetTemporaryDirectory()+"test.bmp")
LoadImage(0, GetTemporaryDirectory()+"test.bmp")
StartDrawing(ImageOutput(0))
  *ptr = DrawingBuffer()
  Debug DrawingBufferPitch()
StopDrawing()
BERESHEIT
User avatar
Regenduft
Enthusiast
Enthusiast
Posts: 121
Joined: Mon Mar 02, 2009 9:20 pm
Location: Germany

Re: CatchRawImage

Post by Regenduft »

wilbert wrote:Currently you would either have to use Plot() for each pixel which results in a lot of procedure calls or use DrawingBuffer().
You can also poke a BMP-Header in front of your raw data and use CatchImage() afterwards. That's how I do it when loading raw sound data, but of course with a WAV-Header and CatchSound(). :wink: To be a bit more precise, I use a header template which I copy and then just modify the needed values before catching. For images it may be a comfortable way to simply use SaveImage() at program initialization to create and rip the needed header template or templates.

I'm not that deep into BMP file format, but maybe the start address field of the header can be alienated to write the header somewhere else instead of directly in front of the raw image data. ...maybe...

PS: I also think a native CatchRawImage() would be nice! :)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: CatchRawImage

Post by wilbert »

Regenduft wrote:You can also poke a BMP-Header in front of your raw data and use CatchImage() afterwards.
The problem with the BMP format is that it doesn't support 32 bit images with an alpha channel.
Otherwise it might have been an option.
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply