基于 image 库将图片转字符(Golang)

一、效果

注:狗狗图片源于百度图片,下载格式为 png

二、原理 

获取图片的 RGB 数值,通过灰度算法计算灰度值,再将灰度值用字符划分区间,按照灰度值所在的区间输出字符,核心代码:

    for j := 0; j < y; j++ {
		for i := 0; i < x; i++ {
            // 1、获取图片的 RGB 数值
			r, g, b, _ := img.At(i, j).RGBA()
			//fmt.Println(uint8(r), uint8(g), uint8(b))
            // 2、计算图片的灰度值
			gray := Gray(uint8(r), uint8(g), uint8(b))
            // 3、根据灰度值所在的字符区间输出字符
			printPic(gray)
		}
		fmt.Println("")
	}

灰度值算法公式

1、浮点算法:Gray = R * 0.3 + G * 0.59 + B * 0.11

2、整数方法:Gray = (R*30 + G*59 + B*11) / 100

3、移位方法:Gray =( R*76 + G*151 + B*28) >> 8

4、平均值法:Gray =(R + G + B)/ 3 

5、仅取绿色:Gray = G

根据灰度值划分字符区间

灰度值介于 0 ~ 255 ,当字符为 18 个时,256 / 18 向下取整为 14,则每个字符区间的差值为 14,例如,0 <= gray <14 时,输出 ‘A’ ,14 <= gray <25 时,输出 ‘B’ ,以此类推。以下提供两个输出方法:

func printPic(gray uint8) {
	charArray := []string{"K", "S", "P", "k", "s", "p", ";", "."}
	index := math.Round(float64(int(gray) * (len(charArray) + 1) / 255))
	if int(index) >= len(charArray) {
		fmt.Print(" ")
	} else {
		fmt.Printf("%s", charArray[int(index)])
	}
}
func printPic(gray uint8) {
	charArray := []string{"M","N","H","Q","$","O","C","?","7",">","!",":","–",";","."}
	index := math.Floor(float64(int(gray) / len(charArray)))
	if int(index) >= len(charArray) {
		fmt.Print(" ")
	} else {
		fmt.Printf("%s", charArray[int(index)])
	}
}

三、完整代码

package utils

/**
 * 图片工具
 *
 * @author Yushanma
 * @since 2022/10/13 18:54
 */

import (
	"bufio"
	"fmt"
	"image"
	"image/color"
	"image/png"
	"log"
	"math"
	"os"
)

func ReadPic(imgFile string) image.Image {
	// 打开图片文件
	f, err := os.Open(imgFile)
	if err != nil {
		log.Fatalln(err)
	}
	defer f.Close()

	// 解析图片
	img, fmtName, err := image.Decode(f)
	if err != nil {
		log.Fatalln(err)
	}

	//fmt.Printf("Name: %v, Bounds: %+v, Color: %+v", fmtName, img.Bounds(), img.ColorModel())
	x := img.Bounds().Size().X
	y := img.Bounds().Size().Y

	fmt.Println(fmtName, x, y)

	out := image.NewRGBA(img.Bounds())

	for j := 0; j < y; j++ {
		for i := 0; i < x; i++ {
			r, g, b, _ := img.At(i, j).RGBA()
			//fmt.Println(uint8(r), uint8(g), uint8(b))
			gray := Gray(uint8(r), uint8(g), uint8(b))
			printPic(gray)
			out.Set(i, j, color.RGBA{R: gray, G: gray, B: gray, A: 255})
		}
		fmt.Println("")
	}

	SavePic(out)

	return img
}

/*
反转,把每个像素点的每个rgb值都与255作差(alpha的值不改变)
r, g, b = 255-r , 255-g , 255-b
*/

func Invert(r, g, b uint8) (uint8, uint8, uint8) {
	return 255 - r, 255 - g, 255 - b
}

func Gray(r, g, b uint8) uint8 {
	//fmt.Println("\ngray", (r+g+b)/3)
	//return (r + g + b) / 3
	return g
}

func SavePic(img *image.RGBA) {
	f, err := os.Create("D:\\GWorkSpace\\CrazyImg\\data\\out2.png")
	if err != nil {
		log.Fatalln(err)
	}
	defer f.Close()
	b := bufio.NewWriter(f)
	err = png.Encode(b, img)
	if err != nil {
		log.Fatalln(err)
	}
	b.Flush()
}

// 输出 V2
func printPic(gray uint8) {
	charArray := []string{"K", "S", "P", "k", "s", "p", ";", "."}
	index := math.Round(float64(int(gray) * (len(charArray) + 1) / 255))
	if int(index) >= len(charArray) {
		fmt.Print(" ")
	} else {
		fmt.Printf("%s", charArray[int(index)])
	}
}
package main

import "CrazyImg/utils"

/**
 * 主入口
 *
 * @author Yushanma
 * @since 2022/10/13 18:57
 */
func main() {
	imgFile := "D:\\GWorkSpace\\CrazyImg\\data\\img0.png"
	utils.ReadPic(imgFile)
}

四、TXT查看效果

效果与字体相关,这里使用的是新宋体-粗体-四号。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余衫马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值