Fillarea and alpha channel

Just starting out? Need help? Post your questions and find answers here.
r7mk4
User
User
Posts: 13
Joined: Tue Aug 02, 2005 2:23 pm

Fillarea and alpha channel

Post by r7mk4 »

Hi,

I'm getting really messed up... :?

I found the code to transform an image with new coordinates for the corners.
Actually the picture is transformed, showed on the windows, grabed into a new image and then I want to make the outline area (grey) transparent.
I tried to use the FillArea-Command which sounds suitable.
But this command is killing my original picture to 100% independent from my given RGBA-Value.
I tried the different DrawingModes, but...

Sorry for the code. It's not nice. But I'm too confused to make it looking better:

Code: Select all


; Enable all the decoders than PureBasic actually supports
;
UseJPEGImageDecoder()
UseTGAImageDecoder()
UsePNGImageDecoder()
UseTIFFImageDecoder()

; Enable all the encoders than PureBasic actually supports
;
UseJPEGImageEncoder()
UsePNGImageEncoder()



Structure QUADBLT_VERTEX 
  x.l 
  y.l 
EndStructure 

Structure QUADBLT_QUAD 
  v.QUADBLT_VERTEX[4] 
EndStructure 

Structure QUADBLT_TRIANGLE 
  v.QUADBLT_VERTEX[3] 
EndStructure 

Procedure QuadBlt(hdcDest.l,*points.QUADBLT_QUAD,hdcSrc.l,lXSrc.l,lYSrc.l,lWidth.l,lHeight.l) 
  If hdcDest=0 Or *points=0 Or hdcSrc=0 
    ProcedureReturn #False 
  EndIf 
  
  GetClipBox_(hdcSrc,clipbox.rect) 
  If lXSrc+lWidth>clipbox\right-clipbox\left Or lYSrc+lHeight>clipbox\bottom-clipbox\top Or lXSrc<0 Or lYSrc<0 Or lWidth<=0 Or lHeight<=0 
    ProcedureReturn #False 
  EndIf 
  rectrgn=CreateRectRgn_(clipbox\left,clipbox\top,clipbox\right,clipbox\bottom) 
  lResult=GetClipRgn_(hdcDest,rectrgn) 
  If lResult=-1 Or rectrgn=0 
    ProcedureReturn #False 
  EndIf 
  
  Triangle2.QUADBLT_TRIANGLE 
  Triangle2\v[0]\x=*points\v[3]\x 
  Triangle2\v[0]\y=*points\v[3]\y 
  Triangle2\v[1]\x=*points\v[2]\x 
  Triangle2\v[1]\y=*points\v[2]\y 
  Triangle2\v[2]\x=*points\v[1]\x 
  Triangle2\v[2]\y=*points\v[1]\y 
  
  rgntriangle1=CreatePolygonRgn_(*points,3,1) 
  rgntriangle2=CreatePolygonRgn_(Triangle2,3,1) 
  
  If lResult<>0 
    CombineRgn_(rgntriangle1,rgntriangle1,rectrgn,#RGN_AND) 
    CombineRgn_(rgntriangle2,rgntriangle2,rectrgn,#RGN_AND) 
  EndIf 
  
  lOldStretchBltMode=SetStretchBltMode_(hdcDest,#COLORONCOLOR) 
  
  SelectClipRgn_(hdcDest,rgntriangle1) 
  PlgBlt_(hdcDest,*points,hdcSrc,lXSrc,lYSrc,lWidth,lHeight,0,0,0) 
  
  SelectClipRgn_(hdcDest,rgntriangle2) 
  PlgBlt_(hdcDest,Triangle2,hdcSrc,lWidth+lXSrc,lHeight+lYSrc,-lWidth,-lHeight,0,0,0) 
  
  SetStretchBltMode_(hdcDest,lOldStretchBltMode) 
  
  If lResult=0 
    SelectClipRgn_(hdcDest,0) 
  Else 
    SelectClipRgn_(hdcDest,rectrgn) 
  EndIf 
  
  DeleteObject_(rectrgn) 
  DeleteObject_(rgntriangle1) 
  DeleteObject_(rgntriangle2) 
EndProcedure 

Dim pt.Point(3) 

OpenWindow(1,0,0,500,400,"TEST") 
LoadImage(1,"f:\bm.bmp") 
MemDC=CreateCompatibleDC_(0) 
SelectObject_(MemDC,ImageID(1)) 

ST=GetTickCount_() 
DC=GetDC_(WindowID(1)) 


pt(0)\x=5
pt(0)\y=5

pt(1)\x=400 
pt(1)\y=15 

pt(2)\x=20 
pt(2)\y=280 

pt(3)\x=300 
pt(3)\y=300 

QuadBlt(DC,@pt(),MemDC,0,0,ImageWidth(1),ImageHeight(1)) 
Repeat 
  
  
Until WindowEvent()=#PB_Event_CloseWindow 

ImageNr = 2
Width   = 400
Height  = 400

hImage = CreateImage(ImageNr,Width,Height,32) 

hDC    = StartDrawing(ImageOutput(ImageNr)) 
BitBlt_(hDC,0,0,400,400,DC,0,0,#SRCCOPY)  
StopDrawing()

If GrabImage((2),(3),0,0,400,400) And StartDrawing(ImageOutput(3))
  DrawingMode(#PB_2DDrawing_AlphaBlend )
  
  FillArea(380, 380, -1, RGBA(255,0,255,175)) ; Ersetze -1 durch $00FF00, und vergleiche das Ergebnis
  StopDrawing()  
EndIf

SaveImage(3,"f:\Stretchedimage.png")
DeleteDC_(MemDC)
ReleaseDC_(WindowID(1),DC) 

and the result under gimp looks like that:
http://imageshack.us/photo/my-images/58 ... ortier.png

Can somebody help me?

Another point is to get rid of the window to paint with the gdi+ stuff. I just want to transform a pic like the TransformSprite3D-Command. But without using sprites.

Cheers
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Fillarea and alpha channel

Post by netmaestro »

Try this code:

Code: Select all

; Enable all the decoders than PureBasic actually supports
;
UseJPEGImageDecoder()
UseTGAImageDecoder()
UsePNGImageDecoder()
UseTIFFImageDecoder()

; Enable all the encoders than PureBasic actually supports
;
UseJPEGImageEncoder()
UsePNGImageEncoder()

Structure QUADBLT_VERTEX
  x.l
  y.l
EndStructure

Structure QUADBLT_QUAD
  v.QUADBLT_VERTEX[4]
EndStructure

Structure QUADBLT_TRIANGLE
  v.QUADBLT_VERTEX[3]
EndStructure

Procedure QuadBlt(hdcDest.l,*points.QUADBLT_QUAD,hdcSrc.l,lXSrc.l,lYSrc.l,lWidth.l,lHeight.l)
  If hdcDest=0 Or *points=0 Or hdcSrc=0
    ProcedureReturn #False
  EndIf
 
  GetClipBox_(hdcSrc,clipbox.rect)
  If lXSrc+lWidth>clipbox\right-clipbox\left Or lYSrc+lHeight>clipbox\bottom-clipbox\top Or lXSrc<0 Or lYSrc<0 Or lWidth<=0 Or lHeight<=0
    ProcedureReturn #False
  EndIf
  rectrgn=CreateRectRgn_(clipbox\left,clipbox\top,clipbox\right,clipbox\bottom)
  lResult=GetClipRgn_(hdcDest,rectrgn)
  If lResult=-1 Or rectrgn=0
    ProcedureReturn #False
  EndIf
 
  Triangle2.QUADBLT_TRIANGLE
  Triangle2\v[0]\x=*points\v[3]\x
  Triangle2\v[0]\y=*points\v[3]\y
  Triangle2\v[1]\x=*points\v[2]\x
  Triangle2\v[1]\y=*points\v[2]\y
  Triangle2\v[2]\x=*points\v[1]\x
  Triangle2\v[2]\y=*points\v[1]\y
 
  rgntriangle1=CreatePolygonRgn_(*points,3,1)
  rgntriangle2=CreatePolygonRgn_(Triangle2,3,1)
 
  If lResult<>0
    CombineRgn_(rgntriangle1,rgntriangle1,rectrgn,#RGN_AND)
    CombineRgn_(rgntriangle2,rgntriangle2,rectrgn,#RGN_AND)
  EndIf
 
  lOldStretchBltMode=SetStretchBltMode_(hdcDest,#COLORONCOLOR)
 
  SelectClipRgn_(hdcDest,rgntriangle1)
  PlgBlt_(hdcDest,*points,hdcSrc,lXSrc,lYSrc,lWidth,lHeight,0,0,0)
 
  SelectClipRgn_(hdcDest,rgntriangle2)
  PlgBlt_(hdcDest,Triangle2,hdcSrc,lWidth+lXSrc,lHeight+lYSrc,-lWidth,-lHeight,0,0,0)
 
  SetStretchBltMode_(hdcDest,lOldStretchBltMode)
 
  If lResult=0
    SelectClipRgn_(hdcDest,0)
  Else
    SelectClipRgn_(hdcDest,rectrgn)
  EndIf
 
  DeleteObject_(rectrgn)
  DeleteObject_(rgntriangle1)
  DeleteObject_(rgntriangle2)
EndProcedure

Dim pt.Point(3)

CreateImage(1,400,400)                      ; Create an original image to test with
StartDrawing(ImageOutput(1))
  Box(0,0,400,400,#Blue)
  Circle(199,199,160,#Yellow)
StopDrawing()

MemDC=CreateCompatibleDC_(0)
SelectObject_(MemDC,ImageID(1))

CreateImage(2,ImageWidth(1),ImageHeight(1)) ; Target image for transformation
transcolor = RGB(255,0,255)                 ; pink, or whatever you want for a transcolor

DC=StartDrawing(ImageOutput(2))
  Box(0,0,400,400,transcolor)               ; start with whole target as transparent color
 
  pt(0)\x=5
  pt(0)\y=5
 
  pt(1)\x=400
  pt(1)\y=15
 
  pt(2)\x=20
  pt(2)\y=280
 
  pt(3)\x=300
  pt(3)\y=300
 
  QuadBlt(DC,@pt(),MemDC,0,0,ImageWidth(1),ImageHeight(1))
StopDrawing()

DeleteDC_(MemDC)

CreateImage(3, ImageWidth(2),ImageHeight(2), 32) ; Final image for converting transparent color to alpha 0's

alpha.a = 255 ; here we can choose an alpha level for the colored parts of the image, 255 would be opaque
              ; Choose a lower number to make the image partially transparent

StartDrawing(ImageOutput(3))
  DrawImage(ImageID(2),0,0)
  DrawingMode(#PB_2DDrawing_AlphaChannel)
  For j=0 To ImageHeight(3)-1
    For i=0 To ImageWidth(3)-1
      thiscolor = Point(i,j)
      If thiscolor&transcolor = transcolor ; Can't use a simple comparison, the color bytes must be isolated
        Plot(i,j,RGBA(0,0,0,0))
      Else 
        Plot(i,j, alpha<<24|transcolor)
      EndIf
    Next
  Next
StopDrawing()

; test it
chex = CreateImage(#PB_Any,20,20)
StartDrawing(ImageOutput(chex))
  Box(0,0,20,20,#White)
  Box(10,0,10,10,RGB(200,200,200))
  Box(0,10,10,10,RGB(200,200,200))
StopDrawing()

hBrush = CreatePatternBrush_(ImageID(chex))

OpenWindow(0,0,0,640,480,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
SetClassLongPtr_(WindowID(0),#GCL_HBRBACKGROUND,hBrush)
InvalidateRect_(WindowID(0),0,1)

ImageGadget(0,120,80,0,0,ImageID(3))

Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow
BERESHEIT
Post Reply