Image Buffer Flipping

General FreeBASIC programming questions.
leopardpm
Posts: 1787
Joined: Feb 28, 2009 20:58

Image Buffer Flipping

Postby leopardpm » Jan 06, 2019 16:08

Is there a built-in way to flip an image buffer horizontally? like a flag in the PUT routine?

or will I have to write a little routine to do it?

I know the various image blitters posted here do it (multiPut, etc), but all I need is this single ability and would rather not include an entire additional library....
badidea
Posts: 1177
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Image Buffer Flipping

Postby badidea » Jan 06, 2019 17:12

Some code, makes a flipped copy:

Code: Select all

#include once "file.bi"

type bitmap_header field = 1
   bfType          as ushort
   bfsize          as ulong
   bfReserved1     as ushort
   bfReserved2     as ushort
   bfOffBits       as ulong
   biSize          as ulong
   biWidth         as ulong
   biHeight        as ulong
   biPlanes        as ushort
   biBitCount      as ushort
   biCompression   as ulong
   biSizeImage     as ulong
   biXPelsPerMeter as ulong
   biYPelsPerMeter as ulong
   biClrUsed       as ulong
   biClrImportant  as ulong
end type

function loadBitmap(byref pImage as any ptr, fileName as string) as integer
   dim as bitmap_header bmpHeader
   if fileExists(filename) then
      open fileName for binary as #1
         get #1, , bmpHeader
      close #1
      pImage = imagecreate(bmpHeader.biWidth, bmpHeader.biHeight)
      bload fileName, pImage
      if pImage = 0 then return -1 else return 0
   end if
   return -1
end function

function vertFlip(pImageSrc as any ptr, byref pImageDst as any ptr) as integer
   dim as integer w, h, bypp, pitch
   dim as ulong ptr pPixSrc, pPixDst
   dim as single r, g, b, intensity
   'get source image info and check things
   if imageinfo(pImageSrc, w, h, bypp, pitch, pPixSrc) <> 0 then return -1
   if bypp <> 4 then return -2 'only 32-bit images
   if pPixSrc = 0 then return -3
   'create dest image, get info and check things
   pImageDst = imagecreate(w, h)
   if pImageDst = 0 then return -4
   if imageinfo(pImageDst, w, h, bypp, pitch, pPixDst) <> 0 then return -5
   if pPixDst = 0 then return -6
   'do the flip source to destination
   pitch shr= 2 'stepping 4 bytes at a time
   pPixDst += (h - 1) * pitch
   for yi as integer = 0 to h - 1
      for xi as integer = 0 to w - 1
         pPixDst[xi] = pPixSrc[xi]
      next
      pPixSrc += pitch
      pPixDst -= pitch
   next
   return 0
end function

function horzFlip(pImageSrc as any ptr, byref pImageDst as any ptr) as integer
   dim as integer w, h, bypp, pitch
   dim as ulong ptr pPixSrc, pPixDst
   dim as single r, g, b, intensity
   'get source image info and check things
   if imageinfo(pImageSrc, w, h, bypp, pitch, pPixSrc) <> 0 then return -1
   if bypp <> 4 then return -2 'only 32-bit images
   if pPixSrc = 0 then return -3
   'create dest image, get info and check things
   pImageDst = imagecreate(w, h)
   if pImageDst = 0 then return -4
   if imageinfo(pImageDst, w, h, bypp, pitch, pPixDst) <> 0 then return -5
   if pPixDst = 0 then return -6
   'do the flip source to destination
   dim as integer xiDst
   pitch shr= 2 'stepping 4 bytes at a time
   for yi as integer = 0 to h - 1
      xiDst = w
      for xi as integer = 0 to w - 1
         xiDst -= 1
         pPixDst[xiDst] = pPixSrc[xi]
      next
      pPixSrc += pitch
      pPixDst += pitch
   next
   return 0
end function

'===============================================================================

dim as any ptr pImage1, pImage2, pImage3
screenres 1000, 600, 32
if loadBitmap(pImage1, "Basil-cathedral-morning_400.bmp") <> 0 then
   print "Error loading bitmap"
   goto theEnd
end if
if horzFlip(pImage1, pImage2) <> 0 then
   print "Error h-flipping"
   goto theEnd
end if
if vertFlip(pImage1, pImage3) <> 0 then
   print "Error v-flipping"
   goto theEnd
end if

put (50, 50), pImage1, pset
put (300, 100), pImage3, pset
put (550, 150), pImage2, pset

theEnd:
if pImage1 <> 0 then imagedestroy(pImage1)
if pImage2 <> 0 then imagedestroy(pImage2)
if pImage3 <> 0 then imagedestroy(pImage3)
sleep

Used image: https://nr100.home.xs4all.nl/badidea/Basil-cathedral-morning_400.bmp
Last edited by badidea on Jan 06, 2019 17:40, edited 1 time in total.
Tourist Trap
Posts: 2614
Joined: Jun 02, 2015 16:24

Re: Image Buffer Flipping

Postby Tourist Trap » Jan 06, 2019 17:40

leopardpm wrote:Is there a built-in way to flip an image buffer horizontally? like a flag in the PUT routine?

or will I have to write a little routine to do it?

I know the various image blitters posted here do it (multiPut, etc), but all I need is this single ability and would rather not include an entire additional library....


I've done this so far:

Code: Select all

 #include "fbgfx.bi"

'initialize the screen for image creation
screenres 300,300,32,2

'create an image
dim as fb.IMAGE ptr img
img = imageCreate (200,200,rgb(120,0,140),32)

line img, (0, 92)-(189,98), rgb(200,200,0), bf
line img, (189,98)-(50,140), rgb(0,200,255)
line img, (0,0)-(199,199), rgb(200,200,55), b

for i as integer = 0 to 10
    line img, (189,95 - i)-(70,40 - i), rgb(200,200,0)
next
put (50,50), img, pset
sleep 1000

'flip the image
dim as integer imgW, imgH, imgbypp, imgpitch, imgsize
dim as ulong ptr imgpixdata
imageInfo img, imgW, imgH, imgbypp, imgpitch, imgpixdata, imgsize

dim as fb.IMAGE ptr flp
flp = imageCreate (imgW,imgH,rgb(0,0,140),32)
dim as integer flpW, flpH, flpbypp, flppitch, flpsize
dim as ulong ptr flppixdata
imageInfo flp, flpW, flpH, flpbypp, flppitch, flppixdata, flpsize

for y as integer = 0 to imgH - 1
    for x as integer = 0 to imgW - 1
        *cptr(ulong ptr, @flppixdata[y*flpH] + sizeOf(ulong)*x\flpbypp) = *cptr(ulong ptr,  @imgpixdata[y*flpH] + 800 - sizeOf(ulong)*x\imgbypp)
    next x
next y

put (50,50), flp, pset

getkey()

But never were able to fix the little shift of 1pixel of the picture. Maybe someone could tell me a fix by the same way here.
badidea
Posts: 1177
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Image Buffer Flipping

Postby badidea » Jan 06, 2019 17:45

Tourist Trap wrote:But never were able to fix the little shift of 1pixel of the picture. Maybe someone could tell me a fix by the same way here.

800 - sizeOf(ulong) * x \ imgbypp
must be
799 - sizeOf(ulong) * x \ imgbypp
or better
(imgW - 1) - sizeOf(ulong) * x \ imgbypp
An 800x??? image is 0 to 799 in x-direction

My code should be faster because I have less math in the loops.

Edit: Some other issue now, image moves up... Your code is too complicated :-p

Code: Select all

*cptr(ulong ptr, @flppixdata[y * flppitch \ flpbypp] + x) = _
*cptr(ulong ptr, @imgpixdata[y * flppitch \ flpbypp] + (imgW - 1) - x)

Or, as I did:

Code: Select all

flppitch shr= 2
for y as integer = 0 to imgH - 1
    for x as integer = 0 to imgW - 1
        *cptr(ulong ptr, @flppixdata[y * flppitch] + x) = _
        *cptr(ulong ptr, @imgpixdata[y * flppitch] + (imgW - 1) - x)
    next x
next y

And if you remove y * flppitch form the x-loop, it is almost the same as mine.
Last edited by badidea on Jan 06, 2019 18:07, edited 5 times in total.
leopardpm
Posts: 1787
Joined: Feb 28, 2009 20:58

Re: Image Buffer Flipping

Postby leopardpm » Jan 06, 2019 17:52

Tourist Trap wrote:But never were able to fix the little shift of 1pixel of the picture. Maybe someone could tell me a fix by the same way here.

the error must occur in this line:

Code: Select all

        *cptr(ulong ptr, @flppixdata[y*flpH] + sizeOf(ulong)*x\flpbypp) = *cptr(ulong ptr,  @imgpixdata[y*flpH] + 800 - sizeOf(ulong)*x\imgbypp)
either a +1 or a -1 must be added somewhere

badidea: that works perfect, and is simple enough and fast enough - thanks, buddy!
D.J.Peters
Posts: 7659
Joined: May 28, 2005 3:28

Re: Image Buffer Flipping

Postby D.J.Peters » Jan 06, 2019 18:16

y*flpH ignores the pitch (flppitch)

bad idea it must be:
a multiply of 16 bytes in palette modes
a multiply of 8 ushorts in 15/16 bit modes
a multiply of 4 ulong in 24/32 bit modes

Joshy
dodicat
Posts: 5554
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Image Buffer Flipping

Postby dodicat » Jan 06, 2019 18:48

Here's another

Code: Select all

Function reverse(Byref im As Any Ptr) As Any Ptr
    #define ppset(_x,_y,colour)    *Cptr(Ulong Ptr,row+ (_y)*pitch+ (_x) Shl 2)  =(colour)
    #define ppoint(_x,_y)          *Cptr(Ulong Ptr,row + (_y)*pitch + (_x) Shl 2)
    Dim As Integer pitch
    Dim As Any Ptr row
    Dim As Ulong Ptr pixel
    Dim As Integer dx,dy
    Imageinfo im,dx,dy,,pitch,row
    Static As Ulong a(dx-1,dy-1)
    For y As Integer=0 To dy-1
        For x As Integer=0 To dx-1
            a(x,y)=ppoint(x,y)
        Next x
    Next y
    For y As Integer=0 To dy-1
        For x As Integer=0 To dx-1
            ppset((dx-1)-x,y,a(x,y))
        Next x
    Next y
    Return im
End Function

'===================================

Screen 19,32
Dim As Any Ptr im=Imagecreate (400,400,rgb(200,200,200))
Windowtitle("Press space key to flip the baloons")
'=========draw to image======
For z As Integer=0 To 20
    Line im,(50+12*z,200+90*Sin(z))-(200,400),Rgb(0,0,0)
    Circle im,(50+12*z,200+90*Sin(z)),20+z,Rgb(z*10,200,255-10*z),,,,f
    Circle im,(50+12*z,200+90*Sin(z)),20+z,Rgb(z*10,0,255-10*z)
Next z
Draw String im,(100,100),"HELLO",Rgb(0,0,0)
Line im,(0,0)-(399,399),0,b
'============================
Color ,Rgb(100,100,255)
Do
   
    Screenlock
    Cls
    Put(200,100),reverse(im),pset
   
    Screenunlock
    Sleep
    Sleep 1,1
Loop Until Inkey=Chr(27)
Sleep
 
Tourist Trap
Posts: 2614
Joined: Jun 02, 2015 16:24

Re: Image Buffer Flipping

Postby Tourist Trap » Jan 06, 2019 19:03

D.J.Peters wrote:y*flpH ignores the pitch (flppitch)

badidea wrote:
Tourist Trap wrote:But never were able to fix the little shift of 1pixel of the picture. Maybe someone could tell me a fix by the same way here.


And if you remove y * flppitch form the x-loop, it is almost the same as mine.

I always had hard times with those things. Thanks to what you posted all it seems better now.
It just doesn't make the images fit in size and color depth if they are different. I leave this for later!

Code: Select all

 #include "fbgfx.bi"

'initialize the screen for image creation
screenres 600,300,32,2

'create an image
dim as fb.IMAGE ptr img
img = imageCreate (500,200,rgb(40,155,70),32)

'draw something
line img, (0, 92)-(189,98), rgb(200,200,0), bf
line img, (189,98)-(50,140), rgb(0,200,255)
line img, (0,0)-(499,199), rgb(200,200,55), b
for i as integer = 0 to 10
    line img, (189,95 - i)-(70,40 - i), rgb(200,200,0)
next
put (50,50), img, pset
sleep 1000

'flip the image
dim as integer imgW, imgH, imgbypp, imgpitch, imgsize
dim as ulong ptr imgpixdata
imageInfo img, imgW, imgH, imgbypp, imgpitch, imgpixdata, imgsize
dim as fb.IMAGE ptr flp
flp = imageCreate (imgW,imgH,rgb(0,255,0),32)

dim as integer flpW, flpH, flpbypp, flppitch, flpsize
dim as ulong ptr flppixdata
imageInfo flp, flpW, flpH, flpbypp, flppitch, flppixdata, flpsize

for y as integer = 0 to flpH - 1
    for x as integer = 0 to (flppitch - 4)\flpbypp
    '*cptr(ulong ptr, @flppixdata[y*flpW] + x) = rgb(200,y,0) ''test
    '*cptr(ulong ptr, @flppixdata[y*flpW] + x) = *cptr(ulong ptr, @imgpixdata[y*imgW] + x) ''simple copy
    *cptr(ulong ptr, @flppixdata[y*flpW] + x) = *cptr(ulong ptr, @imgpixdata[y*imgW] + (flppitch - 4)\flpbypp - x) ''flip
    next x
next y

put (50,50), flp, pset
getkey()
leopardpm
Posts: 1787
Joined: Feb 28, 2009 20:58

Re: Image Buffer Flipping

Postby leopardpm » Jan 06, 2019 19:20

dodicat wrote:Here's another


nice...but...
why do you make a temporary array to hold the color values? since you are going to overwrite the original image anyways, why not just straight modify it, swapping from on end to the other?

would be twice as fast....

actually, was just trying to do that and since the 'swapping' involves a temp location anyways, then it isn't any faster (unless there is a quick swap ability by using the pointer arithmetic)... sorry, my bad...
Tourist Trap
Posts: 2614
Joined: Jun 02, 2015 16:24

Re: Image Buffer Flipping

Postby Tourist Trap » Jan 06, 2019 19:53

For some reason the pitch mudt be divided by 4, or I still don't get it.
Anyway this below is doing the job in 8 and 32 bits. Pushed here because it's still simple, just need a final confirmation.

Code: Select all

 #include "fbgfx.bi"

const colordepth = 8

'initialize the screen for image creation
screenres 600,300,colordepth,2

'create an image
dim as fb.IMAGE ptr img
img = imageCreate (500,200,rgb(40,155,70),colordepth)

'draw something
line img, (0, 92)-(189,98), rgb(200,200,0), bf
line img, (189,98)-(50,140), rgb(0,200,255)
line img, (0,0)-(499,199), 14, b
for i as integer = 0 to 10
    line img, (189,95 - i)-(70,40 - i), rgb(200,200,0)
next
put (50,50), img, pset
sleep 1000

'flip the image
dim as integer imgW, imgH, imgbypp, imgpitch, imgsize
dim as ulong ptr imgpixdata
imageInfo img, imgW, imgH, imgbypp, imgpitch, imgpixdata, imgsize
dim as fb.IMAGE ptr flp
flp = imageCreate (imgW,imgH,rgb(0,255,0),colordepth)

dim as integer flpW, flpH, flpbypp, flppitch, flpsize
dim as ulong ptr flppixdata
imageInfo flp, flpW, flpH, flpbypp, flppitch, flppixdata, flpsize

line flp, (0,0)-(499,199), iif(colordepth>16, rgb(200,0,255), 14), b
for y as integer = 0 to flpH - 1
    for x as integer = 0 to (flppitch - flpbypp)\flpbypp
    *cptr(ulong ptr, @flppixdata[y*(flppitch\4)] + x) = iif(colordepth>16, rgb(200,y,0), y\16) ''test
    *cptr(ulong ptr, @flppixdata[y*(flppitch\4)] + x) = *cptr(ulong ptr, @imgpixdata[y*(flppitch\4)] + x)  ''copy
    next x
next y

? flppitch, flpbypp

put (50,50), flp, pset
getkey()
leopardpm
Posts: 1787
Joined: Feb 28, 2009 20:58

Re: Image Buffer Flipping

Postby leopardpm » Jan 06, 2019 20:00

dodicat, actually this does save time... only half as many 'ppoints'.... and if the image has odd number of pixels then the center pixel is ignored as well...

Code: Select all

Function reverse(Byref im As Any Ptr) As Any Ptr
    #define ppset(_x,_y,colour)    *Cptr(Ulong Ptr,row+ (_y)*pitch+ (_x) Shl 2)  =(colour)
    #define ppoint(_x,_y)          *Cptr(Ulong Ptr,row + (_y)*pitch + (_x) Shl 2)
    Dim As Integer pitch
    Dim As Any Ptr row
    Dim As Ulong Ptr pixel
    Dim As Integer dx,dy
    Imageinfo im,dx,dy,,pitch,row
    Static As Ulong a(dx-1,dy-1)

   
'    For y As Integer=0 To dy-1
'        For x As Integer=0 To dx-1
'            a(x,y)=ppoint(x,y)
'        Next x
'    Next y
'    For y As Integer=0 To dy-1
'        For x As Integer=0 To dx-1
'            ppset((dx-1)-x,y,a(x,y))
'        Next x
'    Next y


'    ' leopard's way...
    dx -= 1 : dy -= 1 'so is not done in the loops....
    dim as ulong tempclr
    For y As Integer=0 To dy
        For x As Integer=0 To dx\2  'only loop thru left side, to swap with right side...
            tempclr = ppoint(x,y)
            ppset (x,y,ppoint((dx)-x,y))
            ppset((dx)-x,y,tempclr)
        Next x
    Next y

    Return im
End Function

'===================================

Screen 19,32
Dim As Any Ptr im=Imagecreate (400,400,rgb(200,200,200))
Windowtitle("Press space key to flip the baloons")
'=========draw to image======
For z As Integer=0 To 20
    Line im,(50+12*z,200+90*Sin(z))-(200,400),Rgb(0,0,0)
    Circle im,(50+12*z,200+90*Sin(z)),20+z,Rgb(z*10,200,255-10*z),,,,f
    Circle im,(50+12*z,200+90*Sin(z)),20+z,Rgb(z*10,0,255-10*z)
Next z
Draw String im,(100,100),"HELLO",Rgb(0,0,0)
Line im,(0,0)-(399,399),0,b
'============================
Color ,Rgb(100,100,255)
Do
   
    Screenlock
    Cls
    Put(200,100),reverse(im),pset
   
    Screenunlock
    Sleep
    Sleep 1,1
Loop Until Inkey=Chr(27)
Sleep
 
Last edited by leopardpm on Jan 06, 2019 20:05, edited 3 times in total.
Tourist Trap
Posts: 2614
Joined: Jun 02, 2015 16:24

Re: Image Buffer Flipping

Postby Tourist Trap » Jan 06, 2019 20:01

@fxm,

INT doesn't replace CINT inside CPTR when doing pointer arithmetic, Is it right?

Code: Select all

cptr(any ptr, x + int(y/z))

doesn't work, whereas same with CINT, yes.
D.J.Peters
Posts: 7659
Joined: May 28, 2005 3:28

Re: Image Buffer Flipping

Postby D.J.Peters » Jan 06, 2019 20:02

In general Is the word "flipping" mirror around X - axis and the word "mirror" around the Y - axis ?

Joshy
leopardpm
Posts: 1787
Joined: Feb 28, 2009 20:58

Re: Image Buffer Flipping

Postby leopardpm » Jan 06, 2019 20:03

D.J.Peters wrote:In general Is the word "flipping" mirror around X - axis and the word "mirror" around the Y - axis ?

Joshy

not really...

you can flip horz (x-axis) or flip vert (y-axis)....

you can mirror horz and mirror vert too


flip and mirror are interchangeable I think

EDIT: all the edits to this post are due to me continually misreading Joshy's post, then changing my answer... lol
dodicat
Posts: 5554
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Image Buffer Flipping

Postby dodicat » Jan 06, 2019 20:16

Tested my flip (horizontal) on a large image.
The times are quite good I think, about .019 here.

Code: Select all

 
Function reverse(Byref im As Any Ptr) As Any Ptr
    #define ppset(_x,_y,colour)    *Cptr(Ulong Ptr,row+ (_y)*pitch+ (_x) Shl 2)  =(colour)
    #define ppoint(_x,_y)          *Cptr(Ulong Ptr,row + (_y)*pitch + (_x) Shl 2)
    Dim As Integer pitch
    Dim As Any Ptr row
    Dim As Ulong Ptr pixel
    Dim As Integer dx,dy
    Imageinfo im,dx,dy,,pitch,row
    Static As Ulong a(dx-1,dy-1)
    For y As Integer=0 To dy-1
        For x As Integer=0 To dx-1
            a(x,y)=ppoint(x,y)
        Next x
    Next y
    For y As Integer=0 To dy-1
        For x As Integer=0 To dx-1
            ppset((dx-1)-x,y,a(x,y))
        Next x
    Next y
    Return im
End Function

'===================================

Screen 20,32
Dim As Any Ptr im=Imagecreate (1000,750,rgb(200,200,200))
Windowtitle("Press space key to flip the baloons")
'=========draw to image======
For z As Integer=0 To 20
    Line im,(50+40*z,  200+90*Sin(z))-(200,400),Rgb(0,0,0)
    Circle im,(50+40*z,200+90*Sin(z)),20+z,Rgb(z*10,200,255-10*z),,,,f
    Circle im,(50+40*z,200+90*Sin(z)),20+z,Rgb(z*10,0,255-10*z)
Next z
for x as long=0 to 999
    for y as long=400 to 749
        pset im,(x,y),rgb(x,x xor y,y)
    next
    next
Draw String im,(100,100),"HELLO",Rgb(0,0,0)
Line im,(0,0)-(999,749),0,b
'============================
Color ,Rgb(100,100,255)
dim as double t1,t2
Do
   
    Screenlock
    Cls
   
    t1=timer
    Put(10,10),reverse(im),pset
    t2=timer
   
    draw string (30,30),"Flipping time  " &(t2-t1),0
    Screenunlock
    Sleep
    Sleep 1,1
Loop Until Inkey=Chr(27)
Sleep
 

(Just a general flip without worrying about odd or even pixels, and not too particular about which compiler to use)

Return to “General”

Who is online

Users browsing this forum: No registered users and 3 guests