Skip to content

Instantly share code, notes, and snippets.

@martinlindhe
Created December 11, 2015 13:52
Show Gist options
  • Save martinlindhe/86192c46ae75a3925b50 to your computer and use it in GitHub Desktop.
Save martinlindhe/86192c46ae75a3925b50 to your computer and use it in GitHub Desktop.
wip..
package main
import (
"bufio"
"fmt"
"image"
"image/draw"
"image/png"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"code.google.com/p/freetype-go/freetype"
"code.google.com/p/freetype-go/freetype/truetype"
"github.com/martinlindhe/decaptcha/imgbox"
"github.com/otiai10/gosseract"
)
func main() {
// gosseractDecode("test/simple/times1.png")
allowedChars := "abcdefghijklmnopqrstuvwxyz" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"0123456789"
initImages("fonts/times32/Times.TTF", allowedChars)
initImages("fonts/times32/Timesbd.TTF", allowedChars) // bold
initImages("fonts/times32/Timesbi.TTF", allowedChars) // bold, italic
initImages("fonts/times32/Timesi.TTF", allowedChars) // italic
}
func loadFont(fontFile string) (font *truetype.Font, err error) {
fontBytes, err := ioutil.ReadFile(fontFile)
if err != nil {
return nil, err
}
font, err = freetype.ParseFont(fontBytes)
if err != nil {
return nil, err
}
return font, nil
}
func initImages(fontFile string, allowedChars string) {
font, err := loadFont(fontFile)
if err != nil {
log.Println(err)
return
}
fontBare := filepath.Base(fontFile)
// XXX 1. init: print letters to images, used later for comparison
for _, size := range []float64{8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0} {
//size := 12.0
tmpDimensions := int(size) + 4
for _, s := range allowedChars {
rgba := image.NewRGBA(image.Rect(0, 0, tmpDimensions, tmpDimensions))
c := freetype.NewContext()
c.SetDPI(72)
c.SetFont(font)
c.SetFontSize(size)
c.SetClip(rgba.Bounds())
c.SetDst(rgba)
c.SetSrc(image.Black)
// XXX small "b" gets cropped with full hinting
//c.SetHinting(freetype.FullHinting)
pt := freetype.Pt(0, int(c.PointToFix32(size)>>8))
_, err := c.DrawString(string(s), pt)
if err != nil {
log.Println(err)
return
}
//asciiAlphaImage(rgba)
rect := imgbox.InnerBox(rgba)
cacheFileName := fmt.Sprintf("%s-%d-%.1f-nohint.png", fontBare, int(s), size)
saveRectToPng(rgba, rect, "cache/"+cacheFileName)
}
}
}
func saveRectToPng(img image.Image, rect image.Rectangle, fileName string) {
// create new image with these dimensions
w := rect.Max.X - rect.Min.X
h := rect.Max.Y - rect.Min.Y
dst := image.NewRGBA(image.Rect(0, 0, w, h))
draw.Draw(dst, dst.Bounds(), img, rect.Min, draw.Src)
saveToPngFile(fileName, dst)
//saveToPngFile("dbg-org.png", img)
//saveToPngFile("dbg-cropped.png", dst)
}
// prints alpha channel of image to console using ascii
func asciiAlphaImage(img image.Image) {
bound := img.Bounds()
for y := bound.Min.Y; y < bound.Max.Y; y++ {
for x := bound.Min.X; x < bound.Max.X; x++ {
val := img.At(x, y)
_, _, _, a := val.RGBA()
if a > 0x8000 {
fmt.Print("X")
} else if a > 0x4000 {
fmt.Print("o")
} else if a > 0 {
fmt.Print(".")
} else {
fmt.Print(" ")
}
}
fmt.Println()
}
}
func saveToPngFile(fileName string, m image.Image) {
f, err := os.Create(fileName)
if err != nil {
log.Println(err)
os.Exit(1)
}
defer f.Close()
b := bufio.NewWriter(f)
err = png.Encode(b, m)
if err != nil {
log.Println(err)
os.Exit(1)
}
err = b.Flush()
if err != nil {
log.Println(err)
os.Exit(1)
}
fmt.Printf("Wrote %s OK.\n", fileName)
}
func gosseractDecode(name string) {
out := gosseract.Must(gosseract.Params{Src: "test/simple/times1.png"})
fmt.Print(strings.TrimSpace(out))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment