From eccf606c5f2dd73f7c810467598cc1781cb3a911 Mon Sep 17 00:00:00 2001 From: Muhammad Saim Date: Sun, 6 Apr 2025 10:46:46 +0500 Subject: [PATCH] fix(avatar): correct grid rendering for odd sizes and eliminate extra margins --- arts/avatar_2.png | Bin 2394 -> 2042 bytes arts/avatar_3.png | Bin 422 -> 377 bytes arts/avatar_6.png | Bin 404 -> 2070 bytes example/main.go | 4 ++-- goavatar.go | 48 ++++++++++++++++++++++++++++++++++------------ 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/arts/avatar_2.png b/arts/avatar_2.png index 0cf75dfa35a88300c36648e4a4a499852b835fd9..ff0675e6b164d88a2e07dd3fcf40d3d1b62b53dd 100644 GIT binary patch literal 2042 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&t&wwUqN(1_t(no-U3d6?5KPH|$$t#o&7J zetgb~$tUM-$Pmi!RQ0h_dKu(dcHK6e)xTlqr;mUCKHsl|h*HssGCL+WV``ZKNN^*g~U%*}ivv(GZJ=xYa{X25 zdA-0w^uX~r4WjDy^IKfCXVwUBU&Oa3g8AH>nfD%knm5^?w&BFZqj%!t|JT>=?68zytzJ-= z{ARWK2iE&`_HVuJ|GRyA{q6bB>sPlkFx1ayU}#WaWMFUv+S$ayz`(-Ez`!BIz#yQ) zz@Xs4z~C@pRKb9S!`yqWR+}p=5^A4-X+SR{t zJdqUyxZGucS|!cWDK87 zS5j>^|NUxrnbe-zuPukq{EV<=d=Ne7&RHHcXg6dG3of1H=FS#_^7Z+{U8+fNdrQPgg&ebxsLQ0B6iw Aj{pDw diff --git a/arts/avatar_3.png b/arts/avatar_3.png index cac3760e8ca138de22c6355e2b4bd0bf52b935d8..667c5f0fa63fe7f913946451f34d122cdb2ef0de 100644 GIT binary patch literal 377 zcmeAS@N?(olHy`uVBq!ia0vp^DImCL?Kk<&SmS^dCKOMUi@LL2 zeEJj4$)X)tU_}bA4;G_A))nw>zkm4r%;!HVvq;` literal 422 zcmeAS@N?(olHy`uVBq!ia0vp^DImbx%$TzI(~0rt z>ZY6iwW;4*i(Ap_+vn4SMWD5KH?KldB@;5K-BF&PwM18FaA95bzCjW4~BT5mdd<=a}6R8w%A^` zwb?oU_y?r}QJK zcMo^pd-nUx{@{wmlIKjVKsFsbd?(K0BK7b5ZR+402i;p3W<^~L`T m?+$4Efl|*ueg=mB|F?aO$h&XDyAN33GkCiCxvXG_AU-vhK&t>&Krzc-3?L`*!>KZ!30J z#e7*^?zzSR1tv(x+da3c&UrTPxKEe@8r;x({pRbi!_Q6DC2nHchzgtHzdh)`xo)Mmj;t-It9+=gMpY17Cf75TZ zJ0H`=mBk;zYl6>W)w%8c??vnFUfG)cJ6Xk*#EJ^J!#^a4-`Q^-*%*Ne50--h`2U{> VYd5d7pFe;c22WQ%mvv4FO#tIXs}=wN diff --git a/example/main.go b/example/main.go index 2ef368d..a47cc3f 100644 --- a/example/main.go +++ b/example/main.go @@ -50,8 +50,8 @@ func main() { var opts []goavatar.OptFunc // add size - opts = append(opts, goavatar.WithSize(100)) - opts = append(opts, goavatar.WithGridSize(10)) + opts = append(opts, goavatar.WithSize(500)) + opts = append(opts, goavatar.WithGridSize(13)) image6 := goavatar.Make("nice__user__name", opts...) // append all the images into the list diff --git a/goavatar.go b/goavatar.go index 3a0ca73..8abf7ea 100644 --- a/goavatar.go +++ b/goavatar.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "image" "image/color" + "math" ) // option contains the configuration for the avatar generator. @@ -68,11 +69,26 @@ func generateHash(data string) string { return hex.EncodeToString(hash[:]) } -// drawPixel draws a single pixel and enlarge each pixle into 20x20 block. -func drawPixel(img *image.RGBA, x, y int, c color.Color, pixelW, pixelH int) { - for dx := 0; dx < pixelW; dx++ { - for dy := 0; dy < pixelH; dy++ { - img.Set(x*pixelW+dx, y*pixelH+dy, c) +// drawPixel draws a single pixel block based on proportional scaling to avoid gaps. +func drawPixel(img *image.RGBA, gridX, gridY int, c color.Color, gridSize, imageSize int) { + // Calculate exact scaled bounds + startX := int(math.Round(float64(gridX) * float64(imageSize) / float64(gridSize))) + startY := int(math.Round(float64(gridY) * float64(imageSize) / float64(gridSize))) + endX := int(math.Round(float64(gridX+1) * float64(imageSize) / float64(gridSize))) + endY := int(math.Round(float64(gridY+1) * float64(imageSize) / float64(gridSize))) + + // Clamp to image size to avoid out-of-bounds + if endX > img.Bounds().Dx() { + endX = img.Bounds().Dx() + } + if endY > img.Bounds().Dy() { + endY = img.Bounds().Dy() + } + + // Fill the block + for y := startY; y < endY; y++ { + for x := startX; x < endX; x++ { + img.Set(x, y, c) } } } @@ -90,12 +106,10 @@ func Make(input string, opts ...OptFunc) image.Image { // create a blank image img := image.NewRGBA(image.Rect(0, 0, o.size, o.size)) - pixelSizeX := o.size / o.gridSize // each grid cell width - pixelSizeY := o.size / o.gridSize // each grid cell height - // generate colors avatarColor := o.fgColor bgColor := o.bgColor + isOdd := o.gridSize%2 != 0 // generate the pixel pattern // loop over each pixel in the grid @@ -106,14 +120,24 @@ func Make(input string, opts ...OptFunc) image.Image { // image should if pixelOn { - drawPixel(img, x, y, avatarColor, pixelSizeX, pixelSizeY) - drawPixel(img, o.gridSize-1-x, y, avatarColor, pixelSizeX, pixelSizeY) // mirror the pixel + drawPixel(img, x, y, avatarColor, o.gridSize, o.size) + drawPixel(img, o.gridSize-1-x, y, avatarColor, o.gridSize, o.size) // mirror the pixel } else { - drawPixel(img, x, y, bgColor, pixelSizeX, pixelSizeY) - drawPixel(img, o.gridSize-1-x, y, bgColor, pixelSizeX, pixelSizeY) // mirror the bg pixel + drawPixel(img, x, y, bgColor, o.gridSize, o.size) + drawPixel(img, o.gridSize-1-x, y, bgColor, o.gridSize, o.size) // mirror the bg pixel } } + // Draw the center column if gridSize is odd + if isOdd { + mid := o.gridSize / 2 + pixelOn := (hash[y]>>(mid%8))&1 == 1 + color := bgColor + if pixelOn { + color = avatarColor + } + drawPixel(img, mid, y, color, o.gridSize, o.size) + } } return img