seekia/imported/goeffects/goeffects.go

207 lines
5.8 KiB
Go

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
}