package img import ( "errors" "image" "image/color" "image/draw" "math" "github.com/disintegration/imaging" "github.com/fogleman/gg" "github.com/ssgo/u" ) // Crop 裁剪图像 func (g *Graphics) Crop(x, y, w, h int) { rect := image.Rect(x, y, x+w, y+h) newImg := imaging.Crop(g.dc.Image(), rect) g.dc = gg.NewContextForImage(newImg) } // Contain 改变图片尺寸,保持图片比例,图片居中 func (g *Graphics) Contain(width, height int) { bounds := g.dc.Image().Bounds() srcW := bounds.Dx() srcH := bounds.Dy() ratio := math.Min(float64(width)/float64(srcW), float64(height)/float64(srcH)) dstW := int(float64(srcW) * ratio) dstH := int(float64(srcH) * ratio) // 创建透明背景画布 newImg := image.NewRGBA(image.Rect(0, 0, width, height)) // 居中放置缩放后的图像 offsetX := (width - dstW) / 2 offsetY := (height - dstH) / 2 resized := imaging.Resize(g.dc.Image(), dstW, dstH, imaging.Lanczos) draw.Draw(newImg, image.Rect(offsetX, offsetY, offsetX+dstW, offsetY+dstH), resized, image.Point{}, draw.Over) g.dc = gg.NewContextForImage(newImg) } // Cover 改变图片尺寸,保持图片比例,图片居中裁剪 func (g *Graphics) Cover(width, height int) { bounds := g.dc.Image().Bounds() srcW := bounds.Dx() srcH := bounds.Dy() ratio := math.Max(float64(width)/float64(srcW), float64(height)/float64(srcH)) dstW := int(float64(srcW) * ratio) dstH := int(float64(srcH) * ratio) resized := imaging.Resize(g.dc.Image(), dstW, dstH, imaging.Lanczos) // 从中心裁剪 cropX := max(0, (dstW-width)/2) cropY := max(0, (dstH-height)/2) cropped := imaging.Crop(resized, image.Rect(cropX, cropY, cropX+width, cropY+height)) g.dc = gg.NewContextForImage(cropped) } // Resize 改变图片尺寸,拉伸 func (g *Graphics) Resize(width, height int, resampleMode *string) { resample := imaging.Lanczos if resampleMode != nil { switch *resampleMode { case "nearest": resample = imaging.NearestNeighbor case "catmullrom": resample = imaging.CatmullRom case "box": resample = imaging.Box case "linear": resample = imaging.Linear case "hermite": resample = imaging.Hermite case "mitchellnetravali": resample = imaging.MitchellNetravali case "bspline": resample = imaging.BSpline case "gaussian": resample = imaging.Gaussian case "bartlett": resample = imaging.Bartlett case "hann": resample = imaging.Hann case "hamming": resample = imaging.Hamming case "blackman": resample = imaging.Blackman case "welch": resample = imaging.Welch case "cosine": resample = imaging.Cosine default: resample = imaging.Lanczos } } resized := imaging.Resize(g.dc.Image(), width, height, resample) g.dc = gg.NewContextForImage(resized) } // Rotate 旋转图像 func (g *Graphics) Rotate(angle float64) { rotated := imaging.Rotate(g.dc.Image(), angle, color.Transparent) g.dc = gg.NewContextForImage(rotated) } // Blur 模糊图像 func (g *Graphics) Blur(sigma float64) { blurred := imaging.Blur(g.dc.Image(), sigma) g.dc = gg.NewContextForImage(blurred) } // Sharpen 锐化图像 func (g *Graphics) Sharpen(sigma float64) { sharpened := imaging.Sharpen(g.dc.Image(), sigma) g.dc = gg.NewContextForImage(sharpened) } // Grayscale 转为灰度图 func (g *Graphics) Grayscale() { gray := imaging.Grayscale(g.dc.Image()) g.dc = gg.NewContextForImage(gray) } // AdjustBrightness 调整亮度 func (g *Graphics) AdjustBrightness(percent float64) { adjusted := imaging.AdjustBrightness(g.dc.Image(), percent) g.dc = gg.NewContextForImage(adjusted) } // AdjustContrast 调整对比度 func (g *Graphics) AdjustContrast(percent float64) { adjusted := imaging.AdjustContrast(g.dc.Image(), percent) g.dc = gg.NewContextForImage(adjusted) } // GammaCorrection Gamma校正 func (g *Graphics) GammaCorrection(gamma float64) { adjusted := imaging.AdjustGamma(g.dc.Image(), gamma) g.dc = gg.NewContextForImage(adjusted) } // FlipH 水平翻转 func (g *Graphics) FlipH() { flipped := imaging.FlipH(g.dc.Image()) g.dc = gg.NewContextForImage(flipped) } // FlipV 垂直翻转 func (g *Graphics) FlipV() { flipped := imaging.FlipV(g.dc.Image()) g.dc = gg.NewContextForImage(flipped) } // AdjustSaturation 调整饱和度 func (g *Graphics) AdjustSaturation(percent float64) { adjusted := imaging.AdjustSaturation(g.dc.Image(), percent) g.dc = gg.NewContextForImage(adjusted) } // func min(a, b int) int { // if a < b { // return a // } // return b // } // func max(a, b int) int { // if a > b { // return a // } // return b // } // Convolve3x3 应用3x3卷积核 func (g *Graphics) Convolve3x3(kernel []float64) error { if len(kernel) != 9 { return errors.New("kernel " + u.String(len(kernel)) + " must be 3x3") } // 获取图像大小 bounds := g.dc.Image().Bounds() width, height := bounds.Dx(), bounds.Dy() // 创建新图像 result := image.NewRGBA(bounds) // 卷积核权重和 var sum float64 for _, v := range kernel { sum += v } // 如果权重和不是0,则使用归一化因子 scale := 1.0 if sum != 0 { scale = 1.0 / sum } // 处理每个像素 for y := 1; y < height-1; y++ { for x := 1; x < width-1; x++ { var r, g1, b, a float64 // 应用卷积核 for ky := -1; ky <= 1; ky++ { for kx := -1; kx <= 1; kx++ { k := kernel[(ky+1)*3+(kx+1)] px := g.dc.Image().At(x+kx, y+ky) pr, pg, pb, pa := px.RGBA() r += float64(pr>>8) * k g1 += float64(pg>>8) * k b += float64(pb>>8) * k a += float64(pa>>8) * k } } // 应用比例因子并限制范围 r = math.Max(0, math.Min(255, r*scale)) g1 = math.Max(0, math.Min(255, g1*scale)) b = math.Max(0, math.Min(255, b*scale)) a = math.Max(0, math.Min(255, a*scale)) // 设置结果像素 result.SetRGBA(x, y, color.RGBA{ R: uint8(r), G: uint8(g1), B: uint8(b), A: uint8(a), }) } } // 复制边界像素 for y := 0; y < height; y++ { for x := 0; x < width; x++ { if y == 0 || y == height-1 || x == 0 || x == width-1 { result.Set(x, y, g.dc.Image().At(x, y)) } } } g.dc = gg.NewContextForImage(result) return nil } // 带强度参数的滤镜应用 func (g *Graphics) ApplyFilter(kernel []float64, strength *float64) error { if len(kernel) != 9 { return errors.New("kernel " + u.String(len(kernel)) + " must be 3x3") } // 创建加权核 weightedKernel := make([]float64, len(kernel)) if strength == nil { copy(weightedKernel, kernel) } else { centerIdx := 4 // 3x3核心中心索引 for i, v := range kernel { if i == centerIdx { weightedKernel[i] = 1 + *strength*(v-1) } else { weightedKernel[i] = *strength * v } } } return g.Convolve3x3(weightedKernel) } // 边缘检测 func (g *Graphics) EdgeDetectionFilter(strength *float64) { g.ApplyFilter([]float64{ -1, -1, -1, -1, 8, -1, -1, -1, -1, }, strength) } // 高斯模糊 func (g *Graphics) GaussianBlurFilter(strength *float64) { g.ApplyFilter([]float64{ 1, 2, 1, 2, 4, 2, 1, 2, 1, }, strength) } // 锐化 func (g *Graphics) SharpenFilter(strength *float64) { g.ApplyFilter([]float64{ -1, -1, -1, -1, 9, -1, -1, -1, -1, }, strength) } // 浮雕 func (g *Graphics) EmbossFilter(strength *float64) { g.ApplyFilter([]float64{ -2, -1, 0, -1, 1, 1, 0, 1, 2, }, strength) } // 散景模糊 func (g *Graphics) BokehFilter(strength *float64) { g.ApplyFilter([]float64{ 0, 0.1, 0, 0.1, 0.6, 0.1, 0, 0.1, 0, }, strength) }