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

前端之家收集整理的这篇文章主要介绍了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"
    "strings"
)

//该工具支持图片色彩反转,图片灰化,图片转为字符画。
//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") {
        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,newGray)
    } 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(" -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,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)
            _,a := colorRgb.RGBA()
            g_uint8 := uint8(g >> 8)
            a_uint8 := uint8(a >> 8)
            newRgba.SetRGBA(i,color.RGBA{g_uint8,a_uint8})
        }
    }
    return newRgba
}

//图片转为字符画
func ascllimage(m image.Image,target string) {
    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)
            _,_ := colorRgb.RGBA()
            avg := uint8(g >> 8)
            num := avg / 18
            dstFile.WriteString(arr[num])
            if j == dx-1 {
                dstFile.WriteString("\n")
            }
        }
    }
}

转换后的结果






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

原文链接:https://www.f2er.com/go/188036.html

猜你在找的Go相关文章