package goeffects // goeffects.go provides functions to interface with go-effects // Package copied from https://github.com/markdaws/go-effects/ import "seekia/internal/helpers" import "seekia/internal/imagery" import "image" import "image/draw" import "errors" func ApplyCartoonEffect(inputImage image.Image, effectStrength int)(image.Image, error){ if (inputImage == nil){ return nil, errors.New("ApplyCartoonEffect called with nil image.") } if (effectStrength < 0 || effectStrength > 100){ return nil, errors.New("ApplyCartoonEffect called with invalid effectStrength.") } if (effectStrength == 0) { return inputImage, nil } blurKernelSize, err := helpers.ScaleIntProportionally(true, effectStrength, 0, 100, 1, 3) if (err != nil) { return nil, err } if (blurKernelSize % 2 == 0){ blurKernelSize += 1 } edgeThreshold, err := helpers.ScaleIntProportionally(false, effectStrength, 0, 100, 5, 200) if (err != nil) { return nil, err } oilFilterSize, err := helpers.ScaleIntProportionally(true, effectStrength, 0, 100, 5, 20) if (err != nil) { return nil, err } oilLevels, err := helpers.ScaleIntProportionally(true, effectStrength, 0, 100, 1, 3) if (err != nil) { return nil, err } options := CTOpts{ BlurKernelSize : blurKernelSize, EdgeThreshold : edgeThreshold, OilFilterSize : oilFilterSize, OilLevels : oilLevels, } cartoonEffectObject := NewCartoon(options) goeffectsImageObject, err := convertGolangImageObjectToGoeffectsImageObject(inputImage) if (err != nil) { return nil, err } resultGoeffectsImage, err := cartoonEffectObject.Apply(&goeffectsImageObject, 8) if (err != nil) { return nil, err } result := convertGoeffectsImageObjectToGolangImageObject(*resultGoeffectsImage) return result, nil } func ApplyPencilEffect(inputImage image.Image, effectStrength int)(image.Image, error){ if (inputImage == nil){ return nil, errors.New("ApplyPencilEffect called with nil image.") } if (effectStrength < 0 || effectStrength > 100){ return nil, errors.New("ApplyPencilEffect called with invalid effectStrength.") } if (effectStrength == 0) { return inputImage, nil } goeffectsImageObject, err := convertGolangImageObjectToGoeffectsImageObject(inputImage) if (err != nil) { return nil, err } blurAmount, err := helpers.ScaleIntProportionally(true, effectStrength, 0, 100, 1, 20) if (err != nil) { return nil, err } if (blurAmount % 2 == 0) { blurAmount += 1 } pencilEffectObject := NewPencil(blurAmount) resultGoeffectsImage, err := pencilEffectObject.Apply(&goeffectsImageObject, 5) if (err != nil) { return nil, err } result := convertGoeffectsImageObjectToGolangImageObject(*resultGoeffectsImage) return result, nil } func ApplyWireframeEffect(inputImage image.Image, effectStrength int, lightMode bool)(image.Image, error){ if (inputImage == nil){ return nil, errors.New("ApplyWireframeEffect called with nil image.") } if (effectStrength < 0 || effectStrength > 100){ return nil, errors.New("ApplyWireframeEffect called with invalid effectStrength.") } if (effectStrength == 0) { return inputImage, nil } goeffectsImageObject, err := convertGolangImageObjectToGoeffectsImageObject(inputImage) if (err != nil) { return nil, err } const algorithm GSAlgo = 3 grayscaleEffectObject := NewGrayscale(algorithm) grayscaleGoeffectsImage, err := grayscaleEffectObject.Apply(&goeffectsImageObject, 5) if (err != nil) { return nil, err } threshold, err := helpers.ScaleIntProportionally(false, effectStrength, 0, 100, 10, 100) if (err != nil) { return nil, err } sobelEffectObject := NewSobel(threshold, lightMode) resultGoeffectsImage, err := sobelEffectObject.Apply(grayscaleGoeffectsImage, 5) if (err != nil) { return nil, err } result := convertGoeffectsImageObjectToGolangImageObject(*resultGoeffectsImage) return result, nil } func ApplyOilPaintingEffect(inputImage image.Image, effectStrength int)(image.Image, error){ if (inputImage == nil){ return nil, errors.New("ApplyOilPaintingEffect called with nil image.") } if (effectStrength < 0 || effectStrength > 100){ return nil, errors.New("ApplyOilPaintingEffect called with invalid effectStrength.") } if (effectStrength == 0) { return inputImage, nil } filterSize, err := helpers.ScaleIntProportionally(true, effectStrength, 0, 100, 10, 30) if (err != nil) { return nil, err } levels, err := helpers.ScaleIntProportionally(true, effectStrength, 0, 100, 10, 70) if (err != nil) { return nil, err } oilPaintingEffectObject := NewOilPainting(filterSize, levels) goeffectsImageObject, err := convertGolangImageObjectToGoeffectsImageObject(inputImage) if (err != nil) { return nil, err } resultGoeffectsImage, err := oilPaintingEffectObject.Apply(&goeffectsImageObject, 5) if (err != nil) { return nil, err } result := convertGoeffectsImageObjectToGolangImageObject(*resultGoeffectsImage) return result, nil } func convertGolangImageObjectToGoeffectsImageObject(inputImage image.Image)(Image, error){ newImageRGBA := image.NewRGBA(inputImage.Bounds()) draw.Draw(newImageRGBA, inputImage.Bounds(), inputImage, image.Point{}, draw.Over) width, height, err := imagery.GetImageWidthAndHeightPixels(inputImage) if (err != nil) { var failedImage Image return failedImage, err } goeffectsImage := Image{ img: newImageRGBA, Width: width, Height: height, Bounds: Rect{X: 0, Y: 0, Width: width, Height: height}, } return goeffectsImage, nil } func convertGoeffectsImageObjectToGolangImageObject(inputImage Image) image.Image { imageRGBA := inputImage.img imageWidth := inputImage.Width imageHeight := inputImage.Height newRectangle := image.Rect(0, 0, imageWidth, imageHeight) newImage := image.NewRGBA(newRectangle) draw.Draw(newImage, newImage.Bounds(), imageRGBA, image.Point{}, draw.Over) return newImage }