Code: Select all
StartDrawing(ImageOutput(imgmap))
BackColor(0)
DrawImage(ImageID(walldef()\image), 15, 15)
StopDrawing()
Code: Select all
StartDrawing(ImageOutput(imgmap))
BackColor(0)
DrawImage(ImageID(walldef()\image), 15, 15)
StopDrawing()
Hi. I'd need the very same function, but my practices with GTK haven't been enough. I also tried to read pixeldata to buffer with Point/Plot operations, but it gets quite slow.This copies waldef()\image onto the imgmap image. waldef()\image was loaded from a bmp file with a black background. How do I do this with the black background being transparent?
Code: Select all
Procedure Blit_Img(src, dst, x, y, TransparentColor = -1)
For xx = 0 To ImageWidth(src) - 1
For yy = 0 To ImageHeight(src) - 1
StartDrawing(ImageOutput(src))
color = Point(xx, yy)
StopDrawing()
If color <> transparentcolor
StartDrawing(ImageOutput(dst))
Plot(x + xx, y+ yy, color)
StopDrawing()
EndIf
Next
Next
EndProcedure
Code: Select all
Procedure ImgDraw(srcImage, dstImage, x, y, ClearColor = -1)
w = ImageWidth(srcImage)
h = ImageHeight(srcImage)
*tmp = AllocateMemory(w * h * 4) ;temporary memory for source image data
StartDrawing(ImageOutput(srcImage))
;loop through the image to collect data
For a = 0 To w-1
For b = 0 To h-1
c.l = Point(a, b) ;get the color
PokeL(*tmp + ((b * w) + (a)) * 4 , c) ;save the color
Next
Next
StopDrawing()
;draw the temporary image data on the destination
StartDrawing(ImageOutput(dstImage))
For a = 0 To w-1
For b = 0 To h-1
c = PeekL(*tmp + ((b * w) + (a)) * 4) ;read the color
If c <> ClearColor
Plot(x + (a-1), y + (b-1), c)
EndIf
Next
Next
StopDrawing()
FreeMemory(*tmp) ;clean up
EndProcedure
If OpenWindow(0, 0, 0, 210, 210, "ImgDraw", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
src = LoadImage(#PB_Any, "test.bmp")
dst = CreateImage(#PB_Any, 200, 200)
StartDrawing(ImageOutput(dst))
Box(0, 0, ImageWidth(dst), ImageHeight(dst), RGB(255, 0, 255))
StopDrawing()
ImgDraw(src, dst, 50, 50, 0)
ImageGadget(#PB_Any, 5, 5, 200, 200, ImageID(dst))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Code: Select all
; inside start-stopdrawing pair
; loads imagedata to *adr Not bigger than 256x256 images
Procedure LoadSlowTransparentImage(*adr,x,y,wid,hei)
Protected x2,y2,x3
Protected wid2,modu
If wid<1 Or hei<1
ProcedureReturn 0
EndIf
If wid*hei>256*256
ProcedureReturn 0
EndIf
wid2=wid>>3
modu=wid & 3
PokeW(*adr,wid) : *adr+2
PokeW(*adr,hei) : *adr+2
For y2=y To y+hei-1
If wid2>0
For x2=x To x+(wid2-1)<<3
PokeL(*adr,Point(x2,y2)) : *adr+4 : x2+1
PokeL(*adr,Point(x2,y2)) : *adr+4 : x2+1
PokeL(*adr,Point(x2,y2)) : *adr+4 : x2+1
PokeL(*adr,Point(x2,y2)) : *adr+4 : x2+1
PokeL(*adr,Point(x2,y2)) : *adr+4 : x2+1
PokeL(*adr,Point(x2,y2)) : *adr+4 : x2+1
PokeL(*adr,Point(x2,y2)) : *adr+4 : x2+1
PokeL(*adr,Point(x2,y2)) : *adr+4
Next
EndIf
If modu>0
For x3=x2 To x2+modu-1
PokeL(*adr,Point(x3,y2)) : *adr+4
Next
EndIf
Next
EndProcedure
; Draws an image from memorybuffer
; It has to be loaded there with LoadTransparentImage(id,x,y,wid,hei)
Procedure DrawSlowTransparentImage(*adr,x,y,c)
Protected x2,y2
Protected wid,hei,d
Protected x3,wid2,modu
wid=PeekW(*adr) : *adr+2
hei=PeekW(*adr) : *adr+2
If wid=0 Or hei=0
ProcedureReturn 0
EndIf
wid2=wid>>3
modu=wid & 3
;CallDebugger. No, call God.
For y2=y To y+hei-1
If wid2>0
For x2=x To x+(wid2-1)<<3
d=PeekL(*adr) : *adr+4 : If d<>c : Plot(x2,y2,d) : EndIf : x2+1
d=PeekL(*adr) : *adr+4 : If d<>c : Plot(x2,y2,d) : EndIf : x2+1
d=PeekL(*adr) : *adr+4 : If d<>c : Plot(x2,y2,d) : EndIf : x2+1
d=PeekL(*adr) : *adr+4 : If d<>c : Plot(x2,y2,d) : EndIf : x2+1
d=PeekL(*adr) : *adr+4 : If d<>c : Plot(x2,y2,d) : EndIf : x2+1
d=PeekL(*adr) : *adr+4 : If d<>c : Plot(x2,y2,d) : EndIf : x2+1
d=PeekL(*adr) : *adr+4 : If d<>c : Plot(x2,y2,d) : EndIf : x2+1
d=PeekL(*adr) : *adr+4 : If d<>c : Plot(x2,y2,d) : EndIf
Next
EndIf
If modu>0
For x3=x2 To x2+modu-1
d=PeekL(*adr) : *adr+4 : If d<>c : Plot(x3,y2,d) : EndIf
Next
EndIf
Next
EndProcedure
; Does the whole procedure. Outside of the start-stopdrawing. As slow as it can get ;)
Procedure SlowTransparentImage(output,img,x,y,c)
StartDrawing(ImageOutput(img))
LoadSlowTransParentImage(*imagebuffer,0,0,ImageWidth(img),ImageHeight(img))
StopDrawing()
StartDrawing(output)
DrawSlowTransparentImage(*imagebuffer,x,y,c)
StopDrawing()
EndProcedure
Back in days when even jumping in the code (such as for-next loop) took Cpu-cycles, it was necessary to reduce the for-next loop and add more operations inside it. This is a low-level optimization, but I didn't really see much improvement with it.Also, Kapslok, I fail to understand why you are poking the same thing 8 times.
Good idea, I'd go for that too. And there was a very simple way to access image data via a windows API function. It can't be much more complex on Linux. Is there anyone who knows how to do this?I was thinking, Instead of saving the image to data, then writing the data over an image, I could possibly read the pixel data of one image and put it on another image's pixel data. I've done this with SDL sprites, but I don't know how to get the pointer to the pixel data of an image.
Code: Select all
Procedure ImgDraw(srcImage, dstImage, x, y, ClearColor=-1)
; Draw image with a transparent colour
Protected dw, dh, w, h, *tmp, a, b, c.lProtected dw, dh, dw0, dh0, w, h, sw0, sh0, *tmp, a, b, c.l
StartDrawing(ImageOutput(srcImage))
w = OutputWidth(): h = OutputHeight()
; Determine the transparent colour
If ClearColor<0
; Use a corner pixel to set the transparent colour
; The ordering of corners (-1..-4) is anticlockwise from the top left
Select ClearColor
Case -2 ; Bottom left
ClearColor = Point(0, h-1)
Case -3 ; Bottom right
ClearColor = Point(w-1, h-1)
Case -4 ; Top right
ClearColor = Point(w-1, 0)
Default ; Top left
ClearColor = Point(0, 0)
EndSelect
EndIf
; If required, clip the image areas
dw = ImageWidth(dstImage): dh = ImageHeight(dstImage)
; Clip destination
If x>=0: dw0 = x: Else: dw0 = 0: EndIf
If y>=0: dh0 = y: Else: dh0 = 0: EndIf
; Clip source
If x>=0: sw0 = 0: Else: sw0 = -x: w + x: EndIf
If y>=0: sh0 = 0: Else: sh0 = -y: h + x: EndIf
If w>dw-dw0: w = dw-dw0: EndIf
If h>dh-dh0: h = dh-dh0: EndIf
If w<=0 Or h<=0: StopDrawing(): ProcedureReturn: EndIf
*tmp = AllocateMemory(w*h*4) ; Temporary memory for source image data
; Loop through the image to collect data
For a = 0 To w-1
For b = 0 To h-1
c = Point(a+sw0, b+sh0) ; Get the color
PokeL(*tmp + (b*w+a)*4, c) ; Save the color
Next
Next
StopDrawing()
; Draw the temporary image data on the destination
StartDrawing(ImageOutput(dstImage))
For a = 0 To w-1
For b = 0 To h-1
c = PeekL(*tmp + (b*w+a)*4) ; Read the color
If c <> ClearColor
Plot(a+dw0, b+dh0, c)
EndIf
Next
Next
StopDrawing()
FreeMemory(*tmp) ; Clean up
EndProcedure