golang实现图片颜色反转、图片灰度、缩放、转为字符画

看到网上很多通过字符形成的画,觉得很好玩,于是网上搜索了下原来叫字符画。
见百度百科:https://baike.baidu.com/item/%E5%AD%97%E7%AC%A6%E7%94%BB/1347002

发现了一篇文章手把手教你图片转ASCII码图 这篇文章采用的是javascript编写的,讲了其中的缘由。

大概原理是首先将图片灰化处理,然后根据灰白图片后的每个像素的rgb值,转成对应的字符,然后就行程了字符图片。

下面是通过go语言实现的图片转换功能

// imagetool project main.go
package main

import (
	"bytes"
	"fmt"
	"image"
	"image/color"
	"image/gif"
	"image/jpeg"
	"image/png"
	"io/ioutil"
	"os"
	"strconv"
	"strings"

	"code.google.com/p/graphics-go/graphics"
)

//该工具支持将图片色彩反转,图片灰化,图片转为字符画。
//author iccboy 2017-9-2
func main() {
	args := os.Args //获取用户输入的所有参数
	if args == nil || len(args) < 4 || !(args[1] == "-r" || args[1] == "-g" || args[1] == "-t" || args[1] == "-c") {
		usage()
		return
	}
	fmt.Print("...转换中...")
	option := args[1]
	source := args[2]
	target := args[3]

	ff, _ := ioutil.ReadFile(source)
	bbb := bytes.NewBuffer(ff)
	m, _, _ := image.Decode(bbb)
	if option == "-r" {
		newRgba := fzImage(m)
		f, _ := os.Create(target)
		defer f.Close()
		encode(source, f, newRgba)
	} else if option == "-g" {
		newGray := hdImage(m)
		f, _ := os.Create(target)
		defer f.Close()
		encode(source, f, newGray)
	} else if option == "-c" {
		rectWidth := 200
		if len(args) > 4 {
			rectWidth, _ = strconv.Atoi(args[4])
		}
		newRgba := rectImage(m, rectWidth)
		f, _ := os.Create(target)
		defer f.Close()
		encode(source, f, newRgba)
	} else {
		ascllimage(m, target)
	}
	fmt.Println("转换完成...")
}

//帮助提示信息
var usage = func() {
	fmt.Println("输入错误,请按照下面的格式输入:")
	fmt.Println("使用: imagetool [OPTION]  source_image [output]")
	fmt.Println("  Options is flow:")
	fmt.Println("    -r         图片颜色翻转")
	fmt.Println("    -g         图片灰度")
	fmt.Println("    -c         缩放文本,该参数时,可以传入图片缩放的宽度 如:imagetool -c 1.jpg c1.jpg 100")
	fmt.Println("    -t         转成文本")

}

//图片编码
func encode(inputName string, file *os.File, rgba *image.RGBA) {
	if strings.HasSuffix(inputName, "jpg") || strings.HasSuffix(inputName, "jpeg") {
		jpeg.Encode(file, rgba, nil)
	} else if strings.HasSuffix(inputName, "png") {
		png.Encode(file, rgba)
	} else if strings.HasSuffix(inputName, "gif") {
		gif.Encode(file, rgba, nil)
	} else {
		fmt.Errorf("不支持的图片格式")
	}
}

//图片色彩反转
func fzImage(m image.Image) *image.RGBA {
	bounds := m.Bounds()
	dx := bounds.Dx()
	dy := bounds.Dy()
	newRgba := image.NewRGBA(bounds)
	for i := 0; i < dx; i++ {
		for j := 0; j < dy; j++ {
			colorRgb := m.At(i, j)
			r, g, b, a := colorRgb.RGBA()
			r_uint8 := uint8(r >> 8)
			g_uint8 := uint8(g >> 8)
			b_uint8 := uint8(b >> 8)
			a_uint8 := uint8(a >> 8)
			r_uint8 = 255 - r_uint8
			g_uint8 = 255 - g_uint8
			b_uint8 = 255 - b_uint8
			newRgba.SetRGBA(i, j, color.RGBA{r_uint8, g_uint8, b_uint8, a_uint8})
		}
	}
	return newRgba
}

//图片灰化处理
func hdImage(m image.Image) *image.RGBA {
	bounds := m.Bounds()
	dx := bounds.Dx()
	dy := bounds.Dy()
	newRgba := image.NewRGBA(bounds)
	for i := 0; i < dx; i++ {
		for j := 0; j < dy; j++ {
			colorRgb := m.At(i, j)
			_, g, _, a := colorRgb.RGBA()
			g_uint8 := uint8(g >> 8)
			a_uint8 := uint8(a >> 8)
			newRgba.SetRGBA(i, j, color.RGBA{g_uint8, g_uint8, g_uint8, a_uint8})
		}
	}
	return newRgba
}

//图片缩放, add at 2018-9-12
func rectImage(m image.Image, newdx int) *image.RGBA {
	bounds := m.Bounds()
	dx := bounds.Dx()
	dy := bounds.Dy()
	newRgba := image.NewRGBA(image.Rect(0, 0, newdx, newdx*dy/dx))
	graphics.Scale(newRgba, m)
	return newRgba
}

//图片转为字符画(简易版)
func ascllimage(m image.Image, target string) {
	if m.Bounds().Dx() > 300 {
		m = rectImage(m, 300)
	}
	bounds := m.Bounds()
	dx := bounds.Dx()
	dy := bounds.Dy()
	arr := []string{"M", "N", "H", "Q", "$", "O", "C", "?", "7", ">", "!", ":", "–", ";", "."}

	fileName := target
	dstFile, err := os.Create(fileName)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	defer dstFile.Close()
	for i := 0; i < dy; i++ {
		for j := 0; j < dx; j++ {
			colorRgb := m.At(j, i)
			_, g, _, _ := colorRgb.RGBA()
			avg := uint8(g >> 8)
			num := avg / 18
			dstFile.WriteString(arr[num])
			if j == dx-1 {
				dstFile.WriteString("\n")
			}
		}
	}
}

由于上面映入了code.google.com的组件,需要手动下载包,或者翻qiang了

转换后的结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DH3Jdlug-1658063938306)(https://img-blog.csdn.net/20170902202154973?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2Nib3kyMDA5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qwyLgAwN-1658063938309)(https://img-blog.csdn.net/20170902202214908?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2Nib3kyMDA5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E2S3YOex-1658063938310)(https://img-blog.csdn.net/20170902202236139?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2Nib3kyMDA5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l6OwPqWt-1658063938311)(https://img-blog.csdn.net/20170902202510179?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2Nib3kyMDA5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DRykecex-1658063938312)(https://img-blog.csdn.net/20170902202306208?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2Nib3kyMDA5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PKmEyiZD-1658063938313)(https://img-blog.csdn.net/20170902210959233?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2Nib3kyMDA5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jp4a4mNd-1658063938314)(https://img-blog.csdn.net/20170902210834339?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2Nib3kyMDA5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]

由于上面的图片不知道怎么失效了,重新上传一次图片
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

从上面的效果可以看出基本功能已经实现,不过还有两个问题需要解决,一个是 gif图片转换后只保留了第一幅图,第二个是“字符画”还并不是字符画,只是一个txt文件,下面一篇文章将优化这个程序,实现gif的字符动画

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IccBoY

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

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

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

打赏作者

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

抵扣说明:

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

余额充值