17 Star 59 Fork 10

王福迎 / asciilize

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
asciilize.go 3.73 KB
一键复制 编辑 原始数据 按行查看 历史
package main
import (
"flag"
"fmt"
"image/jpeg"
"math"
"os"
)
// max block size = 4096 X 4096
// gray to ascii map
var grayMap = [...]string{"@", "w", "#", "$", "k", "d", "t", "j", "i", ".", " "}
func main() {
ptr_filename := flag.String("f", "./a.jpg", "Define the source jpeg file")
ptr_blockX := flag.Int("bx", 5, "Define the block size in X axis")
ptr_blockY := flag.Int("by", 10, "Define the block size in Y axis")
ptr_step := flag.Int("j", 25, "sampling step")
flag.Parse()
_, asciiData, err := Asciilize(*ptr_filename, *ptr_blockX, *ptr_blockY, *ptr_step)
if nil != err || *ptr_blockX < 1 || *ptr_blockY < 1 {
fmt.Println(err)
flag.Usage()
fmt.Println("Example: ./program -f ./hello.jpg -bx 4 -by 6")
fmt.Println("可以使用-j n参数来控制采用的细腻度,表示每n个点取样一次,如果n等于0,则关闭此功能,n=0等价于n=1")
}
OutputAsciilizedData(asciiData)
}
func Asciilize(jpegFile string, blockSizeX int, blockSizeY int, jump int) (grayData [][]uint8, asciiData [][]string, err error) {
blockX := blockSizeX
blockY := blockSizeY
// open file
m_file, err := os.Open(jpegFile)
defer m_file.Close()
if err != nil {
return nil, nil, err
}
// decode jpeg
m_img, err := jpeg.Decode(m_file)
if err != nil {
return nil, nil, err
}
// pre
m_bounds := m_img.Bounds()
// split blocks
nBlockX := (int)(math.Ceil((float64)(m_bounds.Dx()) / float64(blockX)))
nBlockY := (int)(math.Ceil((float64)(m_bounds.Dy()) / float64(blockY)))
// gen 2d array
result := make([][]uint8, nBlockY)
for row := 0; row < nBlockY; row++ {
subresult := make([]uint8, nBlockX, nBlockX)
for col := 0; col < nBlockX; col++ {
subresult[col] = 0
}
result[row] = subresult
}
// calc grey value
var pickColorCount uint = 0
for x := 0; x < nBlockX; x++ {
for y := 0; y < nBlockY; y++ {
// every block
var graySum uint32 = 0
pixelX := x * blockX
pixelY := y * blockY
breakPixel := 0
stepCount := 0
for i := 0; i < blockX; i++ {
for j := 0; j < blockY; j++ {
if 0 != jump {
stepCount %= jump
if 0 != stepCount {
breakPixel++
stepCount++
continue
} else {
stepCount++
}
}
targetX := pixelX + i
targetY := pixelY + j
if targetX >= m_bounds.Dx() || targetY >= m_bounds.Dy() {
breakPixel++
continue
}
// m_color := m_img.At(targetX, targetY)
// gray := image.NewGray(image.Rect(0, 0, m_bounds.Dx(), m_bounds.Dy())).GrayAt(targetX, targetY)
pickColorCount++
r, g, b, a := m_img.At(targetX, targetY).RGBA()
r /= 256
g /= 256
b /= 256
a /= 256
graySum += (uint32)((float64(r)*float64(0.3) + float64(g)*float64(0.59) + float64(b)*float64(0.11)) * (float64(a) / float64(256.0)))
}
}
graySum /= uint32(blockX*blockY - breakPixel)
result[y][x] = uint8(graySum)
}
}
// output pick time
fmt.Printf("Pick Color %d times\n", pickColorCount)
// to ascii 2d array
step := float64(256) / float64(len(grayMap))
// var ascii [][]string
ascii := make([][]string, nBlockY)
for row := 0; row < nBlockY; row++ {
subascii := make([]string, nBlockX)
for col := 0; col < nBlockX; col++ {
index := int(float64(result[row][col]) / step)
subascii[col] = grayMap[index]
}
ascii[row] = subascii
}
grayData = result
asciiData = ascii
return
}
func OutputAsciilizedData(asciiData [][]string) {
// format output
nBlockY := len(asciiData)
if 0 == nBlockY {
return
}
nBlockX := len(asciiData[0])
for row := 0; row < nBlockY; row++ {
for col := 0; col < nBlockX; col++ {
fmt.Print(asciiData[row][col])
}
fmt.Println()
}
}
Go
1
https://gitee.com/wangfuying/asciilize.git
git@gitee.com:wangfuying/asciilize.git
wangfuying
asciilize
asciilize
master

搜索帮助