Reading / Writing Pixels - Really Fast!

Biscuit

Member
Licensed User
Longtime User
Hi

Is there a relatively easy way to be able to read and write pixels in a bitmap very quickly. I've found in other languages e.g. VB6 there was a Plot function which was ok until you wanted to plot a lot of points so then the API SetPixel was found to be faster and then again DirectX was even faster.

I'm not expecting B4A to do anything like this but it seems fairly apparent that e.g. agraham's jpeg library can process the pixels within a 240x320 jpeg in about 0.1 secs but to do something similar on the same device (HTC Wildfire) by using Bitmap.GetPixel() takes much longer.

So I'm just wondering if there is a middle ground where you could get to the underlying bitmap pixels more quickly to process them e.g. if you wanted to calculate their HSV values or do some simple 2D games etc. Perhaps this would be possible in a java library?

Hope this makes sense...?

Thanks
 

agraham

Expert
Licensed User
Longtime User
You can already twiddle pixels with the Jpeg library. Note that you need a 32bit bitmap. Bitmaps created by the Basic4android Bitmap object may only be 16 bit if created from a jpg. They might be 32bit if created from a png with transparency but I haven't checked this.

As well as reading a jpg with LoadJpegArea you can load a (32 bit) Bitmap into the Jpeg library with SetPixelsFromBmp, get and set pixels with GetBmpPixel and SetBmpPixel and get the modified Bitmap with GetBmpFromPixels. It might be worth trying this to see how much faster it is.
 
Upvote 0

Biscuit

Member
Licensed User
Longtime User
Hi

I have created a simple app (attached) to demonstrate something close to what I'm trying to do. Essentially, it could be anything to do with processing some / a lot / all the pixels in an image. Out of curiosity I thought I'd just time some basic loops which seem to run quite slowly even when not really doing any useful work.

The app attached does 4 things:
1) Time the jpeg library to load and return the pixels of a bitmap.
2) Time getting each pixel from a bitmap using Bitmap.GetPixel.
3) Time a simple loop with a nested For that doesn't do much.
4) Time a simple loop with the nested For removed.

The timings I get on an HTC Wildfire are:
1) 0.15 secs
2) 9.12 secs
3) 6.35 secs
4) 3.73 secs

It's a bit of a show stopper if it takes this long just to run a loop that doesn't do much. Any thoughts on any of this stuff would be welcomed. Btw, the resolution of the screen on my wildfire is 240x320.

I don't mean for this to be a critcism of b4a, I just trying to find out what I can and can't do on a mobile device (I've spent all my life programming PCs). B4a is awesome, using stuff like the e.g. PhoneOrientation events is just so easy! I've just always had a nerdy obsession with images & gfx etc and I think I've finally found a development language that I can use to set some of my past creations free :)

Thanks
 

Attachments

  • TestPixelSpeed.zip
    5.2 KB · Views: 418
Upvote 0

Biscuit

Member
Licensed User
Longtime User
Ahem, I've just realised I was running the app in debug mode :signOops:

The same results for the app compiled with no debug info and not running under the debugger are:

1) 0.01 secs
2) 1.82 secs
3) 0.07 secs
4) 0.06 secs

I'll get my coat... :sign0161:

Btw, this is a great result, I'm really pleased and embarrased at the same time :wav::BangHead:
 
Upvote 0

mkvidyashankar

Active Member
Licensed User
Longtime User
Hi

I am using this code to modify the RGB data to sepia tone.

B4X:
 jpg.BmpWidth=bmap.Width
             jpg.BmpHeight=bmap.Height
             jpg.SetPixelsFromBmp(bmap)
            
             Dim rr() As Int
             rr = jpg.BmpPixels
             ' jpg.SetBmpPixel
             
             
            For i = 0 To bmap.Height * bmap.Width - 1
                     col=GetARGB(rr(i))
                  a=col(0)
                  r=Floor(col(1)*0.393+col(2)*0.769+col(3)*0.189) Mod 256
                  g=Floor(col(1)*0.349+col(2)*0.686+col(3)*0.168) Mod 256
                  b=Floor(col(1)*0.272+col(2)*0.534+col(3)*0.131) Mod 256
               Next

It is taking too much time to get it done. Please suggest any alternative method.
 
Upvote 0
Top