Draw Rounded Image

Post your working scripts, libraries and tools for AHK v1.1 and older
jay lee
Posts: 83
Joined: 14 Oct 2021, 11:17

Draw Rounded Image

Post by jay lee » 20 Jan 2024, 20:16

I just recently made this code using some other libraries but because I couldn't really find much on the internet about this I thought I'm just gonna share this with you.

Code: Select all

Class RoundedImage {
    __New(bmp,w,h,rx,ry) {
        Gdip_GetImageDimensions(bmp,w2,h2)
        if(w2 != w || h2 != h) {
            bmp2 := this.FitFullSize(bmp,w,h)
            bmp := bmp2
        }
        bmp2 := Gdip_CreateBitmap(w,h)
        brush := Gdip_CreateTextureBrush(bmp)
        this.path := Gdip_CreatePath()
        g := Gdip_GraphicsFromImage(bmp2)
        x := 0, y := 0
        DllCall("GdiPlus\GdipStartPathFigure", "Ptr", path)
        
        bx := rx*0.5522847498
        this.AddBezier(0,ry,0,ry-bx,rx-bx,0,rx,0)
        this.AddBezier(w-rx,0,w-rx+bx,0,w,bx,w,ry)
        this.AddBezier(w,h-ry,w,h-bx,w-rx+bx,h,w-rx,h)
        this.AddBezier(rx,h,rx-bx,h,0,h-ry+bx,0,h-ry)
        
        
        DllCall("GdiPlus\GdipClosePathFigure", "Ptr", this.path)
        Gdip_FillPath(g,brush,this.path)
        Gdip_DeleteGraphics(g)
        Gdip_DeletePath(path)
        Gdip_DisposeImage(bmp)
        return bmp2
    }
    AddBezier( points* ) {
        
        points := this._FlattenArray(points)
        
        this._CreateBinArray(points, binPoints := "", "Float")
        
        DllCall("GdiPlus\GdipAddPathBeziers"
        , "Ptr",  this.path
        , "Ptr", &binPoints
        , "Int", (points.Length() // 2))
        
        Return this
    }

    _CreateBinArray( srcArray, ByRef binArray, elemType := "UInt", offset := 0 ) {
        Local
        
        Static elemSizes := { "Int64" : 8
        , "Char"  : 1   , "UChar"  : 1
        , "Short" : 2   , "UShort" : 2
        , "Int"   : 4   , "UInt"   : 4
        , "Float" : 4   , "Double" : 8
        , "Ptr"   : A_PtrSize
        , "UPtr"  : A_PtrSize }
        
        If (elemSizes.HasKey(elemType)) {
            elemSize := elemSizes[elemType]
        } Else {
            elemType := "UInt"
            elemSize := 4
        }
        
        VarSetCapacity(binArray, (offset + srcArray.Length()*elemSize), 0)
        elemPos := offset
        
        Loop % srcArray.Length() {
            NumPut( srcArray[A_Index], binArray, elemPos, elemType )
            elemPos += elemSize
        }
    }

    _FlattenArray( srcArray, dstArray := "" ) {
        Local
        Global OGdip
        
        flatArray := IsObject(dstArray)  ?  dstArray  :  []
        
        Loop % srcArray.Length() {
            item := srcArray[A_Index]
            
            If (IsObject(item) && (item.Length() != 0)) {
                this._FlattenArray(item, flatArray)
            } Else {
                flatArray.Push(item)
            }
        }
        
        Return flatArray
    }

    FitFullSize(pBitmap,wsize,hsize) {
        width2 := Gdip_GetImageWidth(pbitmap)
        height2 := Gdip_GetImageHeight(pbitmap)
        wrat := width2 / wsize
        hrat := height2 / hsize
        if(wrat > hrat) {
            height := height2
            width := wsize * hrat
            y := 0
            x := (width2 - width) / 2
        }
        else if(hrat > wrat) {
            width := width2
            height := hsize * wrat
            x := 0
            y := (height2 - height) / 2
        }
        else {
            width := width2
            height := height2
            x := 0
            y := 0
        }
        pBitmapout := Gdip_CreateBitmap(wsize,hsize)
        G := Gdip_GraphicsFromImage(pBitmapout)
        Gdip_DrawImage(G,pBitmap,0,0,wsize,hsize,x,y,width,height)
        Gdip_DeleteGraphics(G)
        Gdip_DisposeImage(pBitmap)
        return pBitmapout
    }
}
credits:
https://github.com/mcl-on-github/oGdip.ahk/tree/main

Return to “Scripts and Functions (v1)”