Skip to content

Instantly share code, notes, and snippets.

@fan123199
Last active March 23, 2020 13:00
Show Gist options
  • Save fan123199/3bf8d1e33af7086d318d40fbc25d2078 to your computer and use it in GitHub Desktop.
Save fan123199/3bf8d1e33af7086d318d40fbc25d2078 to your computer and use it in GitHub Desktop.
golang version image convert to ascii/txt--go版本的图片转字符画
package main
import (
"image"
"image/color"
"os"
"fmt"
"net/http"
"log"
"image/jpeg"
"strconv"
"strings"
"image/png"
"image/gif"
"github.com/kataras/iris/core/errors"
)
//这些值可以去网上搜索,也可以自己算出(还不会)
const str = "@80GCLft1i;:,."
//const str = "##@@MMBB88NNHHOOGGPPEEXXFFVVYY22ZZCC77LLjjll11rrii;;;:::.... "
//编辑器的字符的宽高比, 编辑器的行距太高,不处理可能会变形。这里是vsCode windows版的比例
const wordRatio = float32(36) / float32(15)
//const wordRatio = 1
const (
sizeSmall = 80
sizeMedium = 160
sizeLarge = 320
)
//主要是 image 包的基本使用
func main() {
arg := os.Args
if arg == nil || len(arg) != 3 {
usage()
return
}
size, err := strconv.Atoi(arg[1])
if err != nil {
usage()
return
}
url := arg[2]
// test data
//size := sizeSmall
//url := "https://www.v2ex.com/static/img/v2ex@2x.png"
img := download(url)
rgb := color2Gray(img)
rgbSmall := small(rgb, size, wordRatio)
image2ascii(*rgbSmall)
}
func usage() {
fmt.Println(`格式
size url
`)
}
//下载图片
func download(url string) image.Image {
var err error
resp, err := http.Get(url)
if err != nil {
log.Fatalln(err)
}
defer resp.Body.Close()
var img image.Image
if strings.HasSuffix(url, ".png") {
img, err = png.Decode(resp.Body)
} else if strings.HasSuffix(url, ".jpg") {
img, err = jpeg.Decode(resp.Body)
} else if strings.HasSuffix(url, ".gif") {
img, err = gif.Decode(resp.Body)
} else {
err = errors.New("not an image")
}
if err != nil {
log.Fatalln(err)
}
return img
}
//压缩图片
func small(img *image.RGBA, size int, wordRatio float32) *image.RGBA {
dx := img.Bounds().Dx()
dy := img.Bounds().Dy()
scale := float32(dx) / float32(size)
wh := float32(dx) / float32(dy)
rgbSmall := image.NewRGBA(image.Rect(0, 0, size, int(float32(size)/(wh*wordRatio))))
bounds := rgbSmall.Bounds()
for i := 0; i < bounds.Dx(); i ++ {
for j := 0; j < bounds.Dy(); j++ {
var gray2 int
c2 := img.RGBAAt(int(float32(i)*scale), int(float32(j)*scale*wordRatio))
c3 := img.RGBAAt(int(float32(i)*scale)+1, int(float32(j)*scale*wordRatio))
c4 := img.RGBAAt(int(float32(i)*scale)-1, int(float32(j)*scale*wordRatio))
c5 := img.RGBAAt(int(float32(i)*scale), int(float32(j)*scale*wordRatio-1))
c6 := img.RGBAAt(int(float32(i)*scale), int(float32(j)*scale*wordRatio+1))
gray2 = (int(c2.R) + int(c3.R) + int(c4.R) + int(c5.R) + int(c6.R)) / 5
c := color.RGBA{R: uint8(gray2), G: uint8(gray2), B: uint8(gray2)}
rgbSmall.SetRGBA(i, j, c)
}
}
return rgbSmall
}
//灰度化图片
func color2Gray(img image.Image) (*image.RGBA) {
bounds := img.Bounds()
w := bounds.Dx()
h := bounds.Dy()
newRgba := image.NewRGBA(bounds)
for i := 0; i < w; i ++ {
for j := 0; j < h; j++ {
cl := img.At(i, j)
r, g, b, _ := cl.RGBA()
gray := (r*30 + g*59 + b*11 + 50) / 100
newC := color.RGBA{R: uint8(gray), G: uint8(gray), B: uint8(gray)}
newRgba.SetRGBA(i, j, newC)
}
}
return newRgba
}
//灰度化的图片转文字
func image2ascii(img image.RGBA) {
file, err := os.Create("out.txt")
defer file.Close()
if err != nil {
fmt.Println(err)
}
s, _ := gray2ascii(img)
file.WriteString(s)
}
func gray2ascii(img image.RGBA) (output string, original string) {
bounds := img.Bounds()
w := bounds.Dx()
h := bounds.Dy()
for i := 0; i < h; i ++ {
line := ""
line2 := ""
for j := 0; j < w; j++ {
gray := img.RGBAAt(j, i).R
num := int(gray) * len(str) / 256
line += string(str[num])
line2 += strconv.Itoa(int(gray)) + ","
}
line += "\n"
line2 += "\n"
output += line
original += line2
}
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment