Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Simple Image Manipulation
#1
I wrote a simple program that can flip an image vertically and horizontally, scale it by two, invert the colors, and greyscale it.
Enjoy. Smile

edit:optimized invert color routine to run slightly faster

Code:
enum
    IMG_NONE=1
    IMG_SCALE_2X=2
    IMG_FLIP_VERT=4
    IMG_FLIP_HORZ=8
    IMG_INVERT=16
    IMG_GREY=32
end enum

union color32
    c as integer
    b(3) as ubyte
end union

sub ImageMorph(i as integer ptr,i2 as integer ptr,flags as integer)
    dim as integer wid,hei,tX,tY
    dim as color32 col
    wid=(i[0] shl 16) shr 19
    hei=(i[0] shr 16)
    
    if flags and IMG_SCALE_2X then i2=imagecreate(wid shl 1,hei shl 1,0) else i2=imagecreate(wid,hei,0)
    
    for tX = 0 to wid-1
        for tY = 0 to hei-1
            
            if flags and IMG_FLIP_HORZ then tX=wid-tX-1
            if flags and IMG_FLIP_VERT then tY=hei-tY-1
            
            if flags and IMG_GREY then
                col.c=i[tX+tY*wid+1]
                col.c=col.b(2)*.299+col.b(1)*.587+col.b(0)*.114
                col.b(0)=col.c
                col.b(1)=col.c
                col.b(2)=col.c
            else
                col.c=i[tX+tY*wid+1]
            end if
            
            if flags and IMG_INVERT then
                col.b(0)=col.b(0) xor 255
                col.b(1)=col.b(1) xor 255
                col.b(2)=col.b(2) xor 255
            end if
            
            if flags and IMG_FLIP_HORZ then tX=wid-tX-1
            if flags and IMG_FLIP_VERT then tY=hei-tY-1
            
            if flags and IMG_SCALE_2X then
                i2[(tX shl 1)+(tY shl 1)*(wid shl 1)+1]=col.c
                i2[((tX shl 1) or 1)+((tY shl 1) or 1)*(wid shl 1)+1]=col.c
                i2[(tX shl 1)+((tY shl 1) or 1)*(wid shl 1)+1]=col.c
                i2[((tX shl 1) or 1)+(tY shl 1)*(wid shl 1)+1]=col.c
            else
                i2[tX+tY*wid+1]=col.c
            end if
            
        next
    next
    
end sub


randomize timer

screenres 640,480,32

dim as integer ptr img,img2
dim as integer tC,w=64,h=64,x
dim as integer ptr bla
dim as single tm

'create an example image
img=imagecreate(w,h)
for tC = 1 to 123904
    x=int(rnd*64)
    y=int(rnd*64)
    pset img,(x,y),rgb(x*4,(63-x)*4,y*4)
next

put(0,0),img

tm = timer
for t = 1 to 1000
    ImageMorph(img,img2,IMG_SCALE_2X or IMG_FLIP_VERT or IMG_FLIP_HORZ or IMG_INVERT)' or IMG_GREY)    
next

'show fps
tm=timer-tm
locate h/4+1,1
print 1000/tm;" fps"
put(w,0),img2

sleep

imagedestroy(img2)
[Image: freebasic.png]
Reply
#2
To Deleter:

I just tested your program here and I must say that it is executed so fast and beautifully for 32-bit color! Big Grin=b My results were from 600fps to over 1600fps on the Pionex 450mhz Pentium-III computer that I use! And the flips and grayscales and a scaling bit works as well! Not bad at all, actually!! Cool

Be catching you later, and I like your code very much!! Wink You keep up the good work now!



[Image: file.php?id=32]
- Adigun Azikiwe Polack
One of the Founders of “Aura Flow” ::: Continuing Developer of “Frantic Journey”
Current Developer of “Star Angelic Slugger” ::: Webmaster of the “AAP Official Projects Squad”
Original Creator of the “The New FreeBASIC 8-Bit Palette Machine” and “AFlib2 - Aura Flow Library 2”
url=http://dhost.hopto.org/aapproj/][Image: file.php?id=194][/url]
Your *official* home of the FreeBasic GFX Demo Central, now holding over 150 FB graphics demos so far!!! Big Grin !
Reply
#3
thanks dude, glad to hear it works so fast on slower computers. Smile
[Image: freebasic.png]
Reply
#4
265.242731364507 fps (with all the options)

i have a 450 mhz i think

i like how you're using enum for options
Reply
#5
This kind of thing happens to be one of my weak areas in programming, I understand how the invert works, but as for the rest of it I can only somwhat understand it, I have never shifted bits nor have seen the benifits of doing so. Can you give me a detailed explanation or tutorial on how to do this so I can try to adapt it to SDL?
url=http://www.smithcosoft.com]SmithcoSoft Creations[/url]
"If you make it idiot proof, someone will make a better idiot" - Murphy's Law
Reply
#6
if you understand binary, shifting bits will make a lot more sense.
shl shifts bytes left, shr, shifts them right. in my thing i use them instead of *2 because i *think* that they are faster. to show you that *2 = shl 1, Lets look at a couple of numbers and their binary counterparts.
1 in binary is, well, 1
2 in binary is 10
0001
0010 <- shifted one bit to the left
3 *2 = 6
3 =0101
6= 1010 <- again shifted by one

To better understand my code, you can just replace every shl 1 with * 2, as they are the exact same thing.
[Image: freebasic.png]
Reply
#7
Ya I get how that works, I read that in the manual, but I am not sure how the new image is actually being changed.
url=http://www.smithcosoft.com]SmithcoSoft Creations[/url]
"If you make it idiot proof, someone will make a better idiot" - Murphy's Law
Reply
#8
FB will replace multiplication by constants that are powers of two by shifts already; there's no benefit to obfuscating the code unless the multiplier is not a constant.

Example:
Code:
dim i as integer, n as integer
i = n * 16
Compiles as:
Code:
mov eax, dword ptr [_N]
sal eax, 4
mov dword ptr [_I], eax

Code:
dim i as integer, n as integer
i = n shl 4
Compiles as:
Code:
mov eax, dword ptr [_N]
sal eax, 4
mov dword ptr [_I], eax
Reply
#9
i wondered about that...
[Image: freebasic.png]
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)