Welcome, Guest. Please login or register.

Author Topic: Image resizing.  (Read 2022 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline DoobreyTopic starter

  • Hero Member
  • *****
  • Join Date: Oct 2002
  • Posts: 1876
    • Show only replies by Doobrey
    • http://www.doobreynet.co.uk
Image resizing.
« on: November 26, 2005, 06:56:34 PM »
Does anyone have any good ideas for resizing a 24bit image that doesn't take ages on a 68k CPU ?
Basically I'm trying to resize a cover image from an ID3 tag to fit a 132*132 12 bit screen (Nokia LCD  currently on the parallel port :-D ).
I've currently tried 3 methods, but have problems with each of them.

1. graphics.library's BitMapScale is damn quick, but gives really crappy results( will it even handle 24bit bitmaps on Amigas without cybergfx or p96?)
2. My own scaling, sampling every pixel of the original image and then creating an average RGB value for each pixel of the resized image, best image but slower than treacle.
3. Another routine I did, just sampling the every nth pixel of the original and plotting that to the new image, (where n = orgsize/newsize ), quick but gives results comparable to BitMapScale :(

I also looked at the scaling provided by v45 datatype.library, but I don't want to limit it to OS3.9

Really I'm looking for an method that meets 1/2 way, trading a bit more CPU time for a better image quality
On schedule, and suing
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Image resizing.
« Reply #1 on: November 26, 2005, 08:06:15 PM »
Basically what you are looking for is a bininear resample. That in itself is fairly easy to code but as you have discovered, it is slow. If you need to convert to 12 bits also, you need an error diffusion method if you want to try and preserve the integrity of the image.

It will be quite slow if you use both.

Just for your own use, for 12 bits you might try the following (assuming you have pgs)

Load the 24 bit image into photogenics. Resize it and then save as HAM6 (with dithering). This will basically reduce the colour to 12 bit (ham caveats apply).

Reload and save the data in some sensible format.
int p; // A
 

Offline DoobreyTopic starter

  • Hero Member
  • *****
  • Join Date: Oct 2002
  • Posts: 1876
    • Show only replies by Doobrey
    • http://www.doobreynet.co.uk
Re: Image resizing.
« Reply #2 on: November 26, 2005, 08:32:23 PM »
I did some tests last week with raw image data converted with Photoshop and just did a hacky conversion to 12bit  (r/2,g/2,b/2) and it looked suprisingly good.
 The LCD also has a 256 colour mode in which you could set 8 levels of red and green, and 4 levels of blue. The LCD controller can take a 12bit value and map it to the nearest rgb levels, I had to look really hard to spot any difference between 256 and 4096 mode, so I might end up using 256 col mode just cos it takes 1/2 the time to send the data( Still approx 1 sec to fill the screen!)..but I'm waffling now :roll:

I hit on an idea earlier on, if the org. pic is >= 2x new size, I could do a quick resize to 1/2 org size using a colour average on a 2x2 block, then apply the slower resampling on that. Results were as good as resample of the org. image, but the time taken was only slightly faster :(
Looks like it's time to revert to asm  :crazy:

Quote

(ham caveats apply)

 Yup, always remember to set the Use_Pineapple_Rings flag  :-)
On schedule, and suing
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Image resizing.
« Reply #3 on: November 27, 2005, 12:29:02 AM »
Quote

Doobrey wrote:

I hit on an idea earlier on, if the org. pic is >= 2x new size, I could do a quick resize to 1/2 org size using a colour average on a 2x2 block, then apply the slower resampling on that. Results were as good as resample of the org. image, but the time taken was only slightly faster :(
Looks like it's time to revert to asm  :crazy:



It all comes down to your inner loops. Chances are you can write a decent implementation in C for a simple 4 -> 1 point resample.

Obvious things you can do when processing an image when speed is important

Never, *ever*, even upon pain of death, use a nested loop for x, y that gives you expressions like "pixel[(y*width)+x]" or "pixel
  • [y]" (which typically evaluates to the same thing).


Always use a single, constantly incrementing pointer for the current pixel. If you need the pixel above, below, left or right, just add (or index with) the appropriate offset. Skipping all the multiplications this type of thing can cause is usually a good speed up.

Always use shifts for multiplication and division when using any constant power of 2 (such as averaging the value of four pixels). A good compiler should do this automatically but it never hurts to do it explicitly.

Due to the effects of cache, on a 68040 or 68060 it can be faster (when your source data is in cacheable memory) to write code that manipulates the individual byte components of a pixel rather than trying to load a 32-bit pixel representation to an integer and muck about with it. Experimentation is the key.

Once you have gotten your C code as fast as you can make it, and it still isn't fast enough, then use asm.
int p; // A
 

Offline DoobreyTopic starter

  • Hero Member
  • *****
  • Join Date: Oct 2002
  • Posts: 1876
    • Show only replies by Doobrey
    • http://www.doobreynet.co.uk
Re: Image resizing.
« Reply #4 on: November 27, 2005, 03:28:12 AM »
Quote

Karlos wrote:

Due to the effects of cache, on a 68040 or 68060 it can be faster (when your source data is in cacheable memory) to write code that manipulates the individual byte components of a pixel rather than trying to load a 32-bit pixel representation to an integer and muck about with it. Experimentation is the key.


 Ta for the pointers (no pun intended)
 I just did some tests of an asm version, got it down to 1/2 a second to resample a 600x600 image to 132x132(although that was on WinUAE with JIT enabled :roll: but still waaaaaaay faster than the tests I did with Windows last night!) although that was reading a pixel as a 32bit RGB, I'll have to see what difference it'll make doing it as 3 byte reads..and also how fast it'll work on a real miggy.


Edit:
  Didn't really see any improvement switching to 3x Move.b (ax)+,dx . I just tested it out on my A4000 (040/40)and the same 600x600 ->132x132 resample only takes 0.75 secs..I was expecting something like at least 2-3 secs!
 The only problem now is the time it takes to load with datatypes, guess I'll have to spend an evening testing which ones are quickest... damn I need a life :-P
On schedule, and suing