Skip to content

Instantly share code, notes, and snippets.

@d0rc
Created October 11, 2024 19:34
Show Gist options
  • Save d0rc/a71823e93cb6d74d910919bd88fb68ab to your computer and use it in GitHub Desktop.
Save d0rc/a71823e93cb6d74d910919bd88fb68ab to your computer and use it in GitHub Desktop.
removeBordersWithTolerance...!
func removeBordersWithTolerance(inputPath, outputPath string, tolerance, minBorderWidth int) error {
// Open the input file
file, err := os.Open(inputPath)
if err != nil {
return err
}
defer file.Close()
// Decode the image
img, format, err := image.Decode(file)
if err != nil {
return err
}
// Get image bounds
bounds := img.Bounds()
width, height := bounds.Max.X, bounds.Max.Y
// Function to check if a pixel is different from the background
isDifferent := func(x, y int) bool {
r, g, b, _ := img.At(x, y).RGBA()
bgR, bgG, bgB, _ := img.At(0, 0).RGBA()
diff := math.Abs(float64(r)-float64(bgR)) +
math.Abs(float64(g)-float64(bgG)) +
math.Abs(float64(b)-float64(bgB))
return diff > float64(tolerance*3*256)
}
// Find content edges
var top, bottom, left, right int
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
if isDifferent(x, y) {
top = y
goto foundTop
}
}
}
foundTop:
for y := height - 1; y >= 0; y-- {
for x := 0; x < width; x++ {
if isDifferent(x, y) {
bottom = y
goto foundBottom
}
}
}
foundBottom:
for x := 0; x < width; x++ {
for y := 0; y < height; y++ {
if isDifferent(x, y) {
left = x
goto foundLeft
}
}
}
foundLeft:
for x := width - 1; x >= 0; x-- {
for y := 0; y < height; y++ {
if isDifferent(x, y) {
right = x
goto foundRight
}
}
}
foundRight:
// Apply minimum border width
top = max(minBorderWidth, top-minBorderWidth)
bottom = min(height-minBorderWidth, bottom+minBorderWidth)
left = max(minBorderWidth, left-minBorderWidth)
right = min(width-minBorderWidth, right+minBorderWidth)
// Create the cropped image
croppedImg := image.NewRGBA(image.Rect(0, 0, right-left, bottom-top))
for y := top; y < bottom; y++ {
for x := left; x < right; x++ {
croppedImg.Set(x-left, y-top, img.At(x, y))
}
}
// Save the cropped image
outFile, err := os.Create(outputPath)
if err != nil {
return err
}
defer outFile.Close()
switch format {
case "jpeg":
return jpeg.Encode(outFile, croppedImg, nil)
case "png":
return png.Encode(outFile, croppedImg)
default:
return png.Encode(outFile, croppedImg)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment