Resizing ImageCreate

New to FreeBASIC? Post your questions here.
Post Reply
nimdays
Posts: 236
Joined: May 29, 2014 22:01
Location: West Java, Indonesia

Resizing ImageCreate

Post by nimdays »

Is there any way to resize the buffer created with imagecreate?

Thanks
badidea
Posts: 2636
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Resizing ImageCreate

Post by badidea »

No standard function for that, as far as I know. The implementation probably uses 'malloc' and 'free', so some hack with 'realloc' might be possible.

The alternative is to make a new memory allocation with 'imagecreate' and copy (a part of) the image to the new buffer and destroy the old one.

What should happen with the image in the buffer? Resize/scale as well?
nimdays
Posts: 236
Joined: May 29, 2014 22:01
Location: West Java, Indonesia

Re: Resizing ImageCreate

Post by nimdays »

@badidea, Thanks for your help
I've been working on a very small widget stuff and I wanted to add how to resize it.
Perhaps you have an example how to copy from the buffer to another buffer ?

Below is an example

Code: Select all

type fbitmap
    as ushort wdata
    as any ptr pimage
    as ulong ptr pdata,ppmap 'start pixel & map
end type

type fwidget
    as short x,y
    as ushort w,h
    as ulong bcolor = &hdddddd,fcolor
    as ushort id
    as fbitmap fbm
    as fwidget ptr pnext,pprev
    declare sub init(as short,as short,as ushort,as ushort)
    declare sub redraw()
end type

sub fwidget.init(x as short,y as short,w as ushort,h as ushort)
    this.x = x : this.y = y : this.w = w : this.h = h
end sub

sub fwidget.redraw()
    if this.fbm.pimage = 0 then return
    dim as ulong ptr pd = this.fbm.pdata,pm = this.fbm.ppmap
    for y as integer = 0 to this.h -1
        for x as integer = 0 to this.w -1
            if pm[x] = 0 or pm[x] = this.id then
                pd[x] = this.bcolor
                pm[x] = this.id
            end if
        next x
        pd += this.fbm.wdata : pm += this.fbm.wdata
    next y
end sub

type flabel extends fwidget
    declare constructor(as ushort,as ushort)
    declare constructor(as short,as short,as ushort,as ushort)
end type

constructor flabel(w as ushort,h as ushort)
    this.init(0,0,w,h)
end constructor

constructor flabel(x as short,y as short,w as ushort,h as ushort)
    this.init(x,y,w,h)
end constructor

type fwindow extends fwidget
    as ushort nc
    as fwidget ptr pfchild,plchild
    declare constructor(as ushort,as ushort)
    declare constructor(as short,as short,as ushort,as ushort)
    declare destructor()
    declare sub init_data()
    declare sub add_widget(as fwidget ptr)
end type

constructor fwindow(w as ushort,h as ushort)
    this.init(0,0,w,h) : this.init_data()
end constructor

constructor fwindow(x as short,y as short,w as ushort,h as ushort)
    this.init(x,y,w,h) : this.init_data()
end constructor

destructor fwindow()
    if this.fbm.pimage then imagedestroy(this.fbm.pimage)
    if this.fbm.ppmap then delete[] this.fbm.ppmap
    dim as fwidget ptr p = this.pfchild,ptmp
    while p
        ptmp = p : p = p->pnext
        delete ptmp
    wend
end destructor

sub fwindow.init_data()
    this.fbm.wdata = this.w
    this.fbm.pimage = imagecreate(this.w,this.h,32)
    this.fbm.pdata = this.fbm.pimage + 32
    this.fbm.ppmap = new ulong[this.w * this.h -1]
end sub

sub fwindow.add_widget(p as fwidget ptr)
    this.nc += 1 : p->id = this.nc
    p->fbm = this.fbm
    if p->fbm.pimage then
        dim as integer l = p->y * p->fbm.wdata + p->x
        p->fbm.pdata += l : p->fbm.ppmap += l
    end if
    if this.pfchild = 0 then 'adjust linked
        this.pfchild = p : this.plchild = p : p->redraw() : return
    end if
    p->pprev = this.plchild
    this.plchild->pnext = p
    this.plchild = p
    p->redraw()
end sub

''''''''''''''''''''

const sw = 800,sh = 600,sd = 32
screenres sw,sh,sd

dim as fwindow ptr p = new fwindow(10,10,200,200)
dim as flabel ptr pl = new flabel(10,10,60,30),pl1 = new flabel(100,10,60,30)
pl->bcolor = &hffff : pl1->bcolor = &hff
p->add_widget(pl)
p->add_widget(pl1)
p->redraw()

put (p->x,P->y),p->fbm.pimage

delete p
sleep
UEZ
Posts: 1079
Joined: May 05, 2017 19:59
Location: Germany

Re: Resizing ImageCreate

Post by UEZ »

You can try this function:

Code: Select all

'https://www.codeproject.com/Articles/33838/Image-Processing-Using-C
Private Function ResizeImage(pImage As Any Pointer, iW_new As Ushort, iH_new As Ushort) As Any Pointer
	#Define GetPixelRI(_x, _y)          *Cptr(Ulong Ptr, imgData + _y * pitch + _x Shl 2)
	#Define SetPixelRI(_x, _y, _color)  *Cptr(Ulong Ptr, imgData_Resized + _y * pitch_Resized + _x Shl 2) = (_color)
	#Define Floor(x) 					(((x) * 2.0 - 0.5) Shr 1)
	#Define Ceiling(x) 					(-((-(x) * 2.0 - 0.5) Shr 1))
	#Define Round(x) 					((x + 0.5) Shr 0)
	Dim pImage_Resized As Any Ptr = Imagecreate(iW_new, iH_new, 0, 32)
	Dim As Integer w, h, wr, hr, pitch, pitch_Resized
	Dim As Any Pointer imgData, imgData_Resized

	Imageinfo(pImage, w, h, , pitch, imgData)
	Imageinfo(pImage_Resized, wr, hr, , pitch_Resized, imgData_Resized)
	Union Col
		As Ulong c
		Type 
			As Ubyte b, g, r, a
		End Type
	End Union
	Dim As Single fWidthFactor = w / wr, fHeightFactor = h / hr, fx, fy, nx, ny
	Dim As Ulong cx, cy, fr_x, fr_y
	Dim As Col color1, color2, color3, color4
	Dim As Ubyte nRed, nGreen, nBlue, nAlpha, bp1, bp2

	For x As Ushort = 0 To wr - 1
		For y As Ushort = 0 To hr - 1

			fr_x = Floor(x * fWidthFactor)
			fr_y = Floor(y * fHeightFactor)

			cx = fr_x + 1
			If cx >= w Then cx = fr_x
			cy = fr_y + 1
			If cy >= h Then cy = fr_y

			fx = x * fWidthFactor - fr_x
			fy = y * fHeightFactor - fr_y

			nx = 1.0 - fx
			ny = 1.0 - fy

			color1.c = GetPixelRI(fr_x, fr_y)
			color2.c = GetPixelRI(cx, fr_y)
			color3.c = GetPixelRI(fr_x, cy)
			color4.c = GetPixelRI(cx, cy)

			'red
			bp1 = nx * color1.r + fx * color2.r
			bp2 = nx * color3.r + fx * color4.r
			nRed = ny * bp1 + fy * bp2         

			'green
			bp1 = nx * color1.g + fx * color2.g
			bp2 = nx * color3.g + fx * color4.g
			nGreen = ny * bp1 + fy * bp2

			'blue
			bp1 = nx * color1.b + fx * color2.b
			bp2 = nx * color3.b + fx * color4.b
			nBlue = ny * bp1 + fy * bp2

			'Alpha
			bp1 = nx * color1.a + fx * color2.a
			bp2 = nx * color3.a + fx * color4.a
			nAlpha = ny * bp1 + fy * bp2

			SetPixelRI(x, y, Rgba(nRed, nGreen, nBlue, nAlpha))
		Next
	Next
   Return pImage_Resized
End Function
I'm not sure how to integrate this ResizeImage function properly into your class code. Can you show me please?
nimdays
Posts: 236
Joined: May 29, 2014 22:01
Location: West Java, Indonesia

Re: Resizing ImageCreate

Post by nimdays »

UEZ wrote: Can you show me please?
Thanks for the code, I'll try that. I haven't create the resizing function yet because I wanted to know how to resize the buffer with imagecreate.

Below is the complete code I've been working so far if you want to help. It's still ugly.
My goal is to create a tiny windowing system

Code: Select all

'F Window Project

#include "fbgfx.bi"
using fb

type fbitmap
    as ushort wdata
    as any ptr pimage
    as ulong ptr pdata,ppmap
end type

type fwidget
    as ushort x,y
    as short w,h
    as zstring ptr ptitle
    as ubyte bstyle = 1,ds = 1
    as ulong bcolor = &hdddddd,fcolor
    as ushort id
    as fbitmap fbm
    as fwidget ptr pnext,pprev
    declare sub init(as short,as short,as ushort,as ushort,as string = "")
    declare sub redraw()
    declare destructor()
end type

destructor fwidget()
    '?"des widget " & @this
    if this.ptitle then deallocate(this.ptitle)
end destructor

sub fwidget.init(x as short,y as short,w as ushort,h as ushort,t as string)
    this.x = x : this.y = y : this.w = w : this.h = h
    if len(t) then
        this.ptitle = allocate(len(t) + 1) : *this.ptitle = t
    end if
end sub

sub fwidget.redraw()
    if this.fbm.pimage = 0 then return
    dim as ulong ptr pd = this.fbm.pdata,pm = this.fbm.ppmap
    for y as integer = 0 to this.h -1
        for x as integer = 0 to this.w -1
            if pm[x] = 0 or pm[x] = this.id then
                pd[x] = this.bcolor
                if ds then pm[x] = this.id
            end if
        next x
        pd += this.fbm.wdata
        pm += this.fbm.wdata
    next y
    if this.ds = 0 or this.ptitle = 0 then return
    draw string this.fbm.pimage,(this.x,this.y),*this.ptitle,this.fcolor
end sub

type flabel extends fwidget
    declare constructor(as ushort,as ushort,as string="")
    declare constructor(as short,as short,as ushort,as ushort,as string ="")
end type

constructor flabel(w as ushort,h as ushort,t as string)
    this.init(0,0,w,h,t)
end constructor

constructor flabel(x as short,y as short,w as ushort,h as ushort,t as string)
    this.init(x,y,w,h,t)
end constructor

type fwindow extends fwidget
    as ushort nc,nw,wstyle = 2
    as fwidget ptr pfchild,plchild 
    as fwindow ptr pwcont
    as fwindow ptr pwnext,pwprev
    as fwindow ptr pwfchild,pwlchild
    declare constructor(as ushort,as ushort,as string="")
    declare constructor(as short,as short,as ushort,as ushort,as string="")
    declare destructor()
    declare sub add_widget(as fwidget ptr)
    declare sub add_window(as fwindow ptr)
    declare sub init_data()
    declare function find_window(as ushort)as fwindow ptr
    declare function find_widget(as ushort)as fwidget ptr
end type

constructor fwindow(w as ushort,h as ushort,t as string)
    this.init(0,0,w,h,t) : this.init_data()
end constructor

constructor fwindow(x as short,y as short,w as ushort,h as ushort,t as string)
    this.init(x,y,w,h,t) : this.init_data()
end constructor

destructor fwindow()
    '?"des win " & @this
    if this.fbm.pimage then imagedestroy(this.fbm.pimage)
    if this.fbm.ppmap then delete[] this.fbm.ppmap
    dim as fwidget ptr p = this.pfchild,ptmp
    while p
        ptmp = p : p = p->pnext
        delete ptmp
    wend
    dim as fwindow ptr pw = this.pwfchild,pwtmp
    while pw
        pwtmp = pw : pw = pw->pwnext
        delete pwtmp
    wend
end destructor

sub fwindow.init_data()
    this.ds = 0 'don't draw title
    this.fbm.wdata = this.w
    this.fbm.pimage = imagecreate(this.w,this.h,32)
    this.fbm.pdata = this.fbm.pimage + 32
    this.fbm.ppmap = new ulong[this.w * this.h -1]
end sub

sub fwindow.add_widget(p as fwidget ptr)
    this.nc += 1 : p->id = this.nc
    p->fbm = this.fbm
    if p->fbm.pimage then
        dim as integer l = p->y * p->fbm.wdata + p->x
        p->fbm.pdata += l : p->fbm.ppmap += l
    end if
    if this.pfchild = 0 then 'adjust linked
        this.pfchild = p : this.plchild = p : p->redraw() : return
    end if
    p->pprev = this.plchild
    this.plchild->pnext = p
    this.plchild = p
    p->redraw()
end sub

sub fwindow.add_window(p as fwindow ptr)
    if this.pwfchild = 0 then 'adjust linked
        this.pwfchild = p : this.pwlchild = p : p->redraw() : return
    end if
    p->pwprev = this.pwlchild
    this.pwlchild->pwnext = p
    this.pwlchild = p
    p->redraw()
end sub

function fwindow.find_window(pid as ushort)as fwindow ptr
    dim as fwindow ptr p = this.pwlchild
    while p
        if p->id = pid then return p
        dim as fwindow ptr pwc = p->find_window(pid)
        if pwc then return pwc
        p = p->pwprev
    wend
    return 0
end function

function fwindow.find_widget(pid as ushort)as fwidget ptr
    dim as fwidget ptr p = this.plchild
    while p
        if p->id = pid then return p
        p = p->pprev
    wend
    return 0
end function

type fw
    as ushort sw,sh,sd,nw
    as ulong ptr pscreen,prow,ppmap
    as ubyte bsize = 4,tsize = 26
    as ulong brcolor = &hffff00,tcolor = &hffff,bbcolor = &hff00ff
    as fwindow ptr proot,pcroot
    declare constructor(as ushort,as ushort,as ushort,as ulong = 0)
    declare destructor()
    declare function add_container(as fwindow ptr)as fwindow ptr
    declare sub add_window(as fwindow ptr)
    declare sub draw_window(as fwindow ptr)
    declare function frun()as integer
end type

constructor fw(w as ushort,h as ushort,d as ushort,c as ulong)
    this.sw = w : this.sh = h : this.sd = d
    screenres w,h,d
    this.pscreen = screenptr()
    this.prow = new ulong[h-1]
    this.ppmap = new ulong[w * h-1]
    dim as integer cr
    for i as integer = 0 to h-1
        this.prow[i] = cr : cr += w
    next i
    dim as fwindow ptr p = new fwindow(w,h,"Root Window"),pc,p1
    this.nw += 1 : p->id = this.nw
    p->wstyle = 1 : p->bcolor = c : this.proot = p
    pc = new fwindow(w,h,"Root Window Container")
    this.nw += 1 : pc->id = this.nw
    pc->wstyle = 1 : this.pcroot = pc
    p->redraw()
    p1 = new fwindow(0,h-this.tsize,w,this.tsize,"Panel Window")
    p1->wstyle = 1 : p1->bcolor = &hffff
    dim as flabel ptr pl = new flabel(70,this.tsize,"Start"),pl1
    pl->bcolor = &hffff00 : p1->add_widget(pl)
    pl1 = new flabel(p1->w-70,0,70,this.tsize,"Clock")
    p1->add_widget(pl1)
    this.add_window(p1)
end constructor

destructor fw()
    if this.prow then delete[] this.prow
    if this.ppmap then delete[] this.ppmap
    dim as fwindow ptr p = this.proot,ptmp
    while p
        ptmp = p : p = p->pwnext
        delete ptmp
    wend
end destructor

function fw.add_container(p as fwindow ptr)as fwindow ptr
    dim as fwindow ptr pp
    if p->wstyle >= 2 then
        pp = new fwindow(p->x,p->y,p->w + this.bsize shl 1,p->h + this.bsize shl 1 + this.tsize)
        p->x += this.bsize
        p->y += this.bsize + this.tsize
        dim as flabel ptr plt = new flabel(this.bsize,this.bsize,pp->w-this.tsize-this.bsize shl 1,this.tsize,*p->ptitle),plc
        plt->bcolor = this.tcolor
        pp->add_widget(plt)
        plc = new flabel(pp->w - this.tsize-this.bsize,this.bsize,this.tsize,this.tsize,"X")
        plc->bcolor = this.bbcolor
        pp->add_widget(plc)
    else
        pp = new fwindow(p->x,p->y,p->w,p->h)
    end if
    pp->bcolor = this.brcolor
    p->pwcont = pp
    this.nw += 1 : p->id = this.nw
    this.nw += 1 : pp->id = this.nw
    return pp
end function

sub fw.add_window(p as fwindow ptr)
    this.proot->add_window(p)
    dim as fwindow ptr pp = this.add_container(p)
    this.pcroot->add_window(pp)
    dim as fwindow ptr pc = p->pwfchild
    while pc
        dim as fwindow ptr ppc = this.add_container(pc)
        pp->add_window(ppc)
        pc = pc->pwnext
    wend
end sub

sub fw.draw_window(p as fwindow ptr)
    dim as fwindow ptr pwc = p->pwlchild
    while pwc
        this.draw_window(pwc)
        pwc = pwc->pwprev
    wend
    dim as ulong ptr ps = this.pscreen,pm = this.ppmap
    dim as ulong ptr pd = p->fbm.pdata,pm1 = p->fbm.ppmap
    ps += this.prow[p->y] + p->x
    pm += this.prow[p->y] + p->x
    screenlock()
    for y as integer = 0 to p->h -1
        for x as integer = 0 to p->w -1
            if pm[x] = 0 or loword(pm[x]) = p->id then
                ps[x] = pd[x]
                pm[x] = p->id or pm1[x] shl 16
            end if
        next x
        ps += this.sw : pm += this.sw
        pd += p->fbm.wdata : pm1 += p->fbm.wdata
    next y 
    screenunlock()
    if p->pwcont then this.draw_window(p->pwcont)
end sub
  
function fw.frun()as integer
    dim as ulong ptr pm = this.ppmap
    dim as boolean quit,inside
    dim as integer cx,cy
    dim as ulong pid
    dim as ushort wid,cid
    dim as fwindow ptr p
    dim as fwidget ptr pc
    dim as event ev
    '''''''''''''''
    do
        if screenevent(@ev) then
            select case ev.type
            case EVENT_KEY_REPEAT : if ev.scancode = SC_ESCAPE then quit = true
            case EVENT_MOUSE_ENTER : inside = true
            case EVENT_MOUSE_EXIT : inside = false
            case EVENT_MOUSE_MOVE
                if inside = 0 then continue do
                cx = ev.x : cy = ev.y
                pid = pm[this.prow[cy]+ cx]
                if pid = 0 then continue do
                wid = loword(pid) : cid = hiword(pid)
                if wid = 1 then 'root window
                    p = this.proot
                else
                    if wid and 1 then 'ganjil = window
                        p = this.proot->find_window(wid)
                    else 'genap = container window
                        p = this.pcroot->find_window(wid)
                    end if
                    if p <> 0 and cid <> 0 then
                        pc = p->find_widget(cid)
                    end if
                end if
                windowtitle "Window : " & p & " ID : " & wid & " Widget : " & pc & " CID : " & cid
            case EVENT_MOUSE_BUTTON_PRESS
                if pid = 0 then continue do
                ''code
            case EVENT_MOUSE_BUTTON_RELEASE
                if pid = 0 then continue do
                ''code
            case else
                ''code
            end select
            p = 0 : pc = 0 : pid = 0 : wid = 0 : cid = 0'reset
        end if
        sleep 1
    loop until quit
    return 1
end function

''''''''main''''''

dim as fw ptr fwm = new fw(800,600,32,&h80)
''test
dim as fwindow ptr p = new fwindow(10,10,200,200,"Window 1"),p1,pwin
dim as flabel ptr pl = new flabel(10,10,60,20,"Label 1")
pl->bcolor = &hff : p->add_widget(pl)
p1 = new fwindow(100,100,200,200,"Child Window 1")
p->add_window(p1)
fwm->add_window(p)
pwin = new fwindow(200,140,300,200,"Window 2")
fwm->add_window(pwin)
fwm->draw_window(fwm->proot)
sleep 1000
p->bcolor = &hffffff : pl->bcolor = &h00ff00
pl->redraw() : p->redraw()
fwm->draw_window(p)
''main loop
fwm->frun()

delete fwm
sleep
'''''
UEZ
Posts: 1079
Joined: May 05, 2017 19:59
Location: Germany

Re: Resizing ImageCreate

Post by UEZ »

nimdays wrote:
UEZ wrote: Can you show me please?
Thanks for the code, I'll try that. I haven't create the resizing function yet because I wanted to know how to resize the buffer with imagecreate.

Below is the complete code I've been working so far if you want to help. It's still ugly.
My goal is to create a tiny windowing system

Code: Select all

'F Window Project

#include "fbgfx.bi"
using fb

type fbitmap
    as ushort wdata
    as any ptr pimage
    as ulong ptr pdata,ppmap
end type

type fwidget
    as ushort x,y
    as short w,h
    as zstring ptr ptitle
    as ubyte bstyle = 1,ds = 1
    as ulong bcolor = &hdddddd,fcolor
    as ushort id
    as fbitmap fbm
    as fwidget ptr pnext,pprev
    declare sub init(as short,as short,as ushort,as ushort,as string = "")
    declare sub redraw()
    declare destructor()
end type

destructor fwidget()
    '?"des widget " & @this
    if this.ptitle then deallocate(this.ptitle)
end destructor

sub fwidget.init(x as short,y as short,w as ushort,h as ushort,t as string)
    this.x = x : this.y = y : this.w = w : this.h = h
    if len(t) then
        this.ptitle = allocate(len(t) + 1) : *this.ptitle = t
    end if
end sub

sub fwidget.redraw()
    if this.fbm.pimage = 0 then return
    dim as ulong ptr pd = this.fbm.pdata,pm = this.fbm.ppmap
    for y as integer = 0 to this.h -1
        for x as integer = 0 to this.w -1
            if pm[x] = 0 or pm[x] = this.id then
                pd[x] = this.bcolor
                if ds then pm[x] = this.id
            end if
        next x
        pd += this.fbm.wdata
        pm += this.fbm.wdata
    next y
    if this.ds = 0 or this.ptitle = 0 then return
    draw string this.fbm.pimage,(this.x,this.y),*this.ptitle,this.fcolor
end sub

type flabel extends fwidget
    declare constructor(as ushort,as ushort,as string="")
    declare constructor(as short,as short,as ushort,as ushort,as string ="")
end type

constructor flabel(w as ushort,h as ushort,t as string)
    this.init(0,0,w,h,t)
end constructor

constructor flabel(x as short,y as short,w as ushort,h as ushort,t as string)
    this.init(x,y,w,h,t)
end constructor

type fwindow extends fwidget
    as ushort nc,nw,wstyle = 2
    as fwidget ptr pfchild,plchild 
    as fwindow ptr pwcont
    as fwindow ptr pwnext,pwprev
    as fwindow ptr pwfchild,pwlchild
    declare constructor(as ushort,as ushort,as string="")
    declare constructor(as short,as short,as ushort,as ushort,as string="")
    declare destructor()
    declare sub add_widget(as fwidget ptr)
    declare sub add_window(as fwindow ptr)
    declare sub init_data()
    declare function find_window(as ushort)as fwindow ptr
    declare function find_widget(as ushort)as fwidget ptr
end type

constructor fwindow(w as ushort,h as ushort,t as string)
    this.init(0,0,w,h,t) : this.init_data()
end constructor

constructor fwindow(x as short,y as short,w as ushort,h as ushort,t as string)
    this.init(x,y,w,h,t) : this.init_data()
end constructor

destructor fwindow()
    '?"des win " & @this
    if this.fbm.pimage then imagedestroy(this.fbm.pimage)
    if this.fbm.ppmap then delete[] this.fbm.ppmap
    dim as fwidget ptr p = this.pfchild,ptmp
    while p
        ptmp = p : p = p->pnext
        delete ptmp
    wend
    dim as fwindow ptr pw = this.pwfchild,pwtmp
    while pw
        pwtmp = pw : pw = pw->pwnext
        delete pwtmp
    wend
end destructor

sub fwindow.init_data()
    this.ds = 0 'don't draw title
    this.fbm.wdata = this.w
    this.fbm.pimage = imagecreate(this.w,this.h,32)
    this.fbm.pdata = this.fbm.pimage + 32
    this.fbm.ppmap = new ulong[this.w * this.h -1]
end sub

sub fwindow.add_widget(p as fwidget ptr)
    this.nc += 1 : p->id = this.nc
    p->fbm = this.fbm
    if p->fbm.pimage then
        dim as integer l = p->y * p->fbm.wdata + p->x
        p->fbm.pdata += l : p->fbm.ppmap += l
    end if
    if this.pfchild = 0 then 'adjust linked
        this.pfchild = p : this.plchild = p : p->redraw() : return
    end if
    p->pprev = this.plchild
    this.plchild->pnext = p
    this.plchild = p
    p->redraw()
end sub

sub fwindow.add_window(p as fwindow ptr)
    if this.pwfchild = 0 then 'adjust linked
        this.pwfchild = p : this.pwlchild = p : p->redraw() : return
    end if
    p->pwprev = this.pwlchild
    this.pwlchild->pwnext = p
    this.pwlchild = p
    p->redraw()
end sub

function fwindow.find_window(pid as ushort)as fwindow ptr
    dim as fwindow ptr p = this.pwlchild
    while p
        if p->id = pid then return p
        dim as fwindow ptr pwc = p->find_window(pid)
        if pwc then return pwc
        p = p->pwprev
    wend
    return 0
end function

function fwindow.find_widget(pid as ushort)as fwidget ptr
    dim as fwidget ptr p = this.plchild
    while p
        if p->id = pid then return p
        p = p->pprev
    wend
    return 0
end function

type fw
    as ushort sw,sh,sd,nw
    as ulong ptr pscreen,prow,ppmap
    as ubyte bsize = 4,tsize = 26
    as ulong brcolor = &hffff00,tcolor = &hffff,bbcolor = &hff00ff
    as fwindow ptr proot,pcroot
    declare constructor(as ushort,as ushort,as ushort,as ulong = 0)
    declare destructor()
    declare function add_container(as fwindow ptr)as fwindow ptr
    declare sub add_window(as fwindow ptr)
    declare sub draw_window(as fwindow ptr)
    declare function frun()as integer
end type

constructor fw(w as ushort,h as ushort,d as ushort,c as ulong)
    this.sw = w : this.sh = h : this.sd = d
    screenres w,h,d
    this.pscreen = screenptr()
    this.prow = new ulong[h-1]
    this.ppmap = new ulong[w * h-1]
    dim as integer cr
    for i as integer = 0 to h-1
        this.prow[i] = cr : cr += w
    next i
    dim as fwindow ptr p = new fwindow(w,h,"Root Window"),pc,p1
    this.nw += 1 : p->id = this.nw
    p->wstyle = 1 : p->bcolor = c : this.proot = p
    pc = new fwindow(w,h,"Root Window Container")
    this.nw += 1 : pc->id = this.nw
    pc->wstyle = 1 : this.pcroot = pc
    p->redraw()
    p1 = new fwindow(0,h-this.tsize,w,this.tsize,"Panel Window")
    p1->wstyle = 1 : p1->bcolor = &hffff
    dim as flabel ptr pl = new flabel(70,this.tsize,"Start"),pl1
    pl->bcolor = &hffff00 : p1->add_widget(pl)
    pl1 = new flabel(p1->w-70,0,70,this.tsize,"Clock")
    p1->add_widget(pl1)
    this.add_window(p1)
end constructor

destructor fw()
    if this.prow then delete[] this.prow
    if this.ppmap then delete[] this.ppmap
    dim as fwindow ptr p = this.proot,ptmp
    while p
        ptmp = p : p = p->pwnext
        delete ptmp
    wend
end destructor

function fw.add_container(p as fwindow ptr)as fwindow ptr
    dim as fwindow ptr pp
    if p->wstyle >= 2 then
        pp = new fwindow(p->x,p->y,p->w + this.bsize shl 1,p->h + this.bsize shl 1 + this.tsize)
        p->x += this.bsize
        p->y += this.bsize + this.tsize
        dim as flabel ptr plt = new flabel(this.bsize,this.bsize,pp->w-this.tsize-this.bsize shl 1,this.tsize,*p->ptitle),plc
        plt->bcolor = this.tcolor
        pp->add_widget(plt)
        plc = new flabel(pp->w - this.tsize-this.bsize,this.bsize,this.tsize,this.tsize,"X")
        plc->bcolor = this.bbcolor
        pp->add_widget(plc)
    else
        pp = new fwindow(p->x,p->y,p->w,p->h)
    end if
    pp->bcolor = this.brcolor
    p->pwcont = pp
    this.nw += 1 : p->id = this.nw
    this.nw += 1 : pp->id = this.nw
    return pp
end function

sub fw.add_window(p as fwindow ptr)
    this.proot->add_window(p)
    dim as fwindow ptr pp = this.add_container(p)
    this.pcroot->add_window(pp)
    dim as fwindow ptr pc = p->pwfchild
    while pc
        dim as fwindow ptr ppc = this.add_container(pc)
        pp->add_window(ppc)
        pc = pc->pwnext
    wend
end sub

sub fw.draw_window(p as fwindow ptr)
    dim as fwindow ptr pwc = p->pwlchild
    while pwc
        this.draw_window(pwc)
        pwc = pwc->pwprev
    wend
    dim as ulong ptr ps = this.pscreen,pm = this.ppmap
    dim as ulong ptr pd = p->fbm.pdata,pm1 = p->fbm.ppmap
    ps += this.prow[p->y] + p->x
    pm += this.prow[p->y] + p->x
    screenlock()
    for y as integer = 0 to p->h -1
        for x as integer = 0 to p->w -1
            if pm[x] = 0 or loword(pm[x]) = p->id then
                ps[x] = pd[x]
                pm[x] = p->id or pm1[x] shl 16
            end if
        next x
        ps += this.sw : pm += this.sw
        pd += p->fbm.wdata : pm1 += p->fbm.wdata
    next y 
    screenunlock()
    if p->pwcont then this.draw_window(p->pwcont)
end sub
  
function fw.frun()as integer
    dim as ulong ptr pm = this.ppmap
    dim as boolean quit,inside
    dim as integer cx,cy
    dim as ulong pid
    dim as ushort wid,cid
    dim as fwindow ptr p
    dim as fwidget ptr pc
    dim as event ev
    '''''''''''''''
    do
        if screenevent(@ev) then
            select case ev.type
            case EVENT_KEY_REPEAT : if ev.scancode = SC_ESCAPE then quit = true
            case EVENT_MOUSE_ENTER : inside = true
            case EVENT_MOUSE_EXIT : inside = false
            case EVENT_MOUSE_MOVE
                if inside = 0 then continue do
                cx = ev.x : cy = ev.y
                pid = pm[this.prow[cy]+ cx]
                if pid = 0 then continue do
                wid = loword(pid) : cid = hiword(pid)
                if wid = 1 then 'root window
                    p = this.proot
                else
                    if wid and 1 then 'ganjil = window
                        p = this.proot->find_window(wid)
                    else 'genap = container window
                        p = this.pcroot->find_window(wid)
                    end if
                    if p <> 0 and cid <> 0 then
                        pc = p->find_widget(cid)
                    end if
                end if
                windowtitle "Window : " & p & " ID : " & wid & " Widget : " & pc & " CID : " & cid
            case EVENT_MOUSE_BUTTON_PRESS
                if pid = 0 then continue do
                ''code
            case EVENT_MOUSE_BUTTON_RELEASE
                if pid = 0 then continue do
                ''code
            case else
                ''code
            end select
            p = 0 : pc = 0 : pid = 0 : wid = 0 : cid = 0'reset
        end if
        sleep 1
    loop until quit
    return 1
end function

''''''''main''''''

dim as fw ptr fwm = new fw(800,600,32,&h80)
''test
dim as fwindow ptr p = new fwindow(10,10,200,200,"Window 1"),p1,pwin
dim as flabel ptr pl = new flabel(10,10,60,20,"Label 1")
pl->bcolor = &hff : p->add_widget(pl)
p1 = new fwindow(100,100,200,200,"Child Window 1")
p->add_window(p1)
fwm->add_window(p)
pwin = new fwindow(200,140,300,200,"Window 2")
fwm->add_window(pwin)
fwm->draw_window(fwm->proot)
sleep 1000
p->bcolor = &hffffff : pl->bcolor = &h00ff00
pl->redraw() : p->redraw()
fwm->draw_window(p)
''main loop
fwm->frun()

delete fwm
sleep
'''''
I think that I've understood now what you mean with resize image buffer after I ran your code from above.
For example you want to resize a window without scaling the content, same as resizing a windows explorer window. In this case the ResizeImage function is the correct one.
My first idea is to create a new image with the new size and copy the content to it from the old image. I'm not aware that it possible to extend the memory of the image on the fly.
badidea
Posts: 2636
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Resizing ImageCreate

Post by badidea »

nimdays wrote:Perhaps you have an example how to copy from the buffer to another buffer ?
I have no example ready, but it should be possible with put :
Put [target, ] [ [STEP](x, y), source [, (x1, y1)-[STEP](x2, y2) ] [, method [, ( alphaval|value|blender [, param]) ] ]
Or get :
Get [source,] [STEP](x1, y1) - [STEP](x2, y2), dest
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Resizing ImageCreate

Post by dodicat »

Create image in it's own likeness.
frames for fun

Code: Select all

 
 
#define pushtop(a) ubound(a)+1
#define poptop(a) ubound(a)
#define bottom(a) lbound(a)

#macro push(a,index,insert)
If (index)>=Lbound(a) And (index)<=Ubound(a)+1 Then
    Var index2=(index)-Lbound(a)
    Redim Preserve a(Lbound(a) To  Ubound(a)+1)
    For x As Long= Ubound(a) To Lbound(a)+index2+1 Step -1
        Swap a(x),a(x-1)
    Next x
    a(Lbound(a)+index2)=(insert)
End If
#endmacro

#macro pop(a,index)
If index>=Lbound(a) And (index)<=Ubound(a) Then
    For x As Long=(index) To Ubound(a)-1
        a(x)=a(x+1)
    Next x
    Redim Preserve a(Lbound(a) To Ubound(a)-1)
End If
#endmacro

#macro revamp(_t_)
scope
var diff=1-lbound(_t_)
redim preserve _t_(1 to ubound(_t_)+diff)
end scope
#endmacro

Type frame
    Private:
    As Long x,y
    As Long w,h
    as zstring * 50 caption
    Declare Sub show()
    Declare Function map(a As Single,b As Single,x As Single,c As Single,d As Single) As Single
    Declare Function overlapped(() As frame) As Long
    as ulong p(any)
    Public:
    Declare Constructor
    Declare Constructor(W As Long,h As Long,col As Ulong,px As Long,py As Long,as string)
    declare sub update()
    Declare Sub MoveByMouse(As Long, As Long, As Long,x() As frame)
    Declare static Sub showscreen(() As Frame)
    Declare Function InImage(As Long,As Long) As Long
    declare function inbox(as long,as long) as long
    Declare static Sub destroy(() As frame)
    declare sub createimage(as long,as long,as ulong)
    declare sub write(as long,as long,as string)
End Type

Constructor frame
if screenptr=0 then print "No graphics screen!":sleep:end
End Constructor

Constructor frame(Wd As Long,hi As Long,col As Ulong,px As Long,py As Long,cap as string)
If Screenptr=0 Then this.constructor
createimage(wd,hi,col)
x=px:y=py
w=Wd:h=Hi
Var b=(h+w)/4
For k As Single=1 To b\10
    Var z=map(1,b/10,k,1,.1)
    Var r=Cptr(Ubyte Ptr,@col)[2]
    Var g=Cptr(Ubyte Ptr,@col)[1]
    Var b=Cptr(Ubyte Ptr,@col)[0]
    Line @p(0),(k,k)-(w-k,h-k),Rgb(r*z,g*z,b*z),b
Next k
line @p(0),(b\10,b\10)-(wd-b\10,30),rgb(0,100,255),bf
draw string @p(0),(wd-b\10-8,b\10),"X",rgb(200,0,0)
draw string @p(0),(b\10,b\10),cap
End Constructor

sub frame.update()
' . . .
end sub

Sub frame.show()
    Put(x,y),@p(0),trans
End Sub

Function frame.Overlapped(f() As Frame) As Long
    Dim As Long px(1 To 8),py(1 To 8)
    For n As Long=1 To Ubound(f)
        px(1)=f(n).x:py(1)=f(n).y
        px(2)=f(n).x+f(n).w:py(2)=f(n).y
        px(3)=f(n).x+f(n).w:py(3)=f(n).y+f(n).h
        px(4)=f(n).x:py(4)=f(n).y+f(n).h
       
        px(5)=(px(1)+px(2))/2:py(5)=(py(1)+py(2))/2
        px(6)=(px(2)+px(3))/2:py(6)=(py(2)+py(3))/2
        px(7)=(px(3)+px(4))/2:py(7)=(py(3)+py(4))/2
        px(8)=(px(4)+px(1))/2:py(8)=(py(4)+py(1))/2
        For n2 As Long=1 To 8
            For k As Long=1 To Ubound(f)
                If f(k).InImage(px(n2),py(n2)) Then Return -1
            Next k
        Next n2
    Next n
    Return 0
End Function

Function frame.map(a As Single,b As Single,x As Single,c As Single,d As Single) As Single
    Return ((d)-(c))*((x)-(a))/((b)-(a))+(c)
End Function

Sub frame.showscreen(n() As frame)
    Screenlock
    Cls
    For m As Long=1 To Ubound(n)
        n(m).show
    Next m
    Screenunlock
    Sleep 1,1
End Sub

Sub Frame.MoveByMouse(mx As Long,my As Long,button As Long,n() As frame)
    Dim As Long x1=mx,y1=my,dx,dy,b
    Dim As Long idx=x-mx,idy=y-my
    While button = 1
        showscreen(n())
        Getmouse mx,my,,button
        If mx>0 And my>0 Then
            If mx<>x1 Or my<>y1  Then
                dx = mx-x1
                dy = my-y1
                x1 = mx
                y1 = my
                Var i2=This
                x=x1+dx+idx
                y=y1+dy+idy
                If Overlapped(n()) Then This=i2:Exit Sub
            End If
        End If
    Wend
End Sub

Function Frame.InImage(mx As Long,my As Long) As Long
    if ubound(p) then Return mx<x+w Andalso mx>x Andalso my<y+h And my>y
End Function

function Frame.inbox(mx as long,my as long) as long
  var b=(h+w)/4
  return mx>(x+w-b\10-16)and mx<(x+w-b\10) and my>(y+b\10) and my<(y+b\10+16)
end function

Sub frame.destroy(f() As frame)
  erase f
  windowtitle "THE END"
End Sub

sub frame.createimage(w as long,h as long,clr as ulong=rgba(255,0,255,255))
    #define pad(n) (n)+(n) mod 16
    redim  p(w*h+8)
    p(0)=7              'always
    p(1)=4              'pixelsize
    p(2)=w              'width
    p(3)=h              'height
    p(4)=pad(w*p(1))    'pitch -- padded to a multiple of 16
    for a as long=5 to 7
        p(a)=0          'reserved
    next
    for a as long=8 To h*w +8 -1
        p(a)=clr        'colour
        next
end sub

sub frame.write(xp as long=0,yp as long=0,s as string)
  draw string @p(0),(xp,yp),s
end sub



screen 20,32
redim as frame f()
push(f,pushtop(f),frame(200,100,Rgb(200,0,100),40,40,"window 1"))
push(f,pushtop(f),frame(200,150,Rgb(0,200,0),140,140,"Window 2"))
push(f,pushtop(f),frame(100,300,Rgb(0,0,200),340,400,"Window 3"))
push(f,pushtop(f),frame(200,300,Rgb(200,10,255),540,400,"Window 4"))
push(f,pushtop(f),frame(300,150,Rgb(200,100,0),640,40,"Window 5"))
revamp(f) 'set one based array
Dim As Long mx,my,mb,flag

Do
    Getmouse mx,my,,mb
     for n as long=lbound(f) to ubound(f)
      If f(n).InImage(mx,my) Then f(n).MoveByMouse(mx,my,mb,f())
      if f(n).inbox(mx,my) and mb=1 and flag=0 then
        flag=1
        if ubound(f)=1 then frame.destroy(f()):exit for
        pop(f,n)
        exit for
      end if
    next n
    if ubound(f)=1 then f(1).write(20,50,"Last one")
    frame.showscreen(f())
    flag=mb
Loop Until Len(Inkey)

frame.destroy(f())
Sleep

 
 
nimdays
Posts: 236
Joined: May 29, 2014 22:01
Location: West Java, Indonesia

Re: Resizing ImageCreate

Post by nimdays »

Thanks All, Really apreciate it
Post Reply