golang 命令行生成样机图片

因为工作需要把一批图片按照样机处理成固定的样子,就用 golang 写了一个小脚本来处理

package main

import (
    "flag"
    "fmt"
    "github.com/nfnt/resize"
    "image"
    "image/draw"
    "image/jpeg"
    "image/png"
    "io/ioutil"
    "os"
    "path/filepath"
    "strconv"
    "strings"
    "sync"
    "time"
)

var wg sync.WaitGroup

func main()  {
    start := time.Now()
    dir, err := os.Getwd()
    if err != nil {
        fmt.Println(err)
    }

    // 待存在目录
    var picDir string
    // 保存目录
    var out string
    // 模板 ID
    var template int

    flag.StringVar(&picDir, "p", "", "请输入待处理图片的目录")
    flag.StringVar(&out, "o", "", "请输入保存图片的目录")
    flag.IntVar(&template, "t", 0, "请输入模板:1-3")
    flag.Parse()


    if picDir == "" {
        fmt.Println("请输入待处理图片的目录")
        return
    }
    if out == "" {
        fmt.Println("请输入保存图片的目录")
        return
    }

    exit, _ := PathExists(out)
    if !exit {
        err := os.Mkdir(out, 0777)
        if err != nil {
            panic(err)
        }
    }

    if template == 0 {
        fmt.Println("请输入模板")
        return
    }
    if template > 3 && template < 1 {
        fmt.Println("模板只能在1-3")
        return
    }

    suffixList := [] string {
        ".jpg",
        ".jpeg",
        ".png",
    }
    picList, err := GetAllFiles(picDir, suffixList)
    if err != nil {
        panic(err)
    }

    if len(picList) == 0 {
        fmt.Println(picDir + " 文件夹下面没有图片")
        return
    }

    for _, pic := range picList {
        wg.Add(1) // 启动一个goroutine就登记+1
        switch template {
            case 1:
                baseTpl := dir + "\\template\\01.jpg"
                go template1(baseTpl, out, pic)
                break
            case 2:
                baseTpl := dir + "\\template\\02.jpg"
                go template2(baseTpl, out, pic)
                break
            case 3:
                baseTpl := dir + "\\template\\03.jpg"
                go template3(baseTpl, out, pic)
                break
        }
    }

    wg.Wait() // 等待所有登记的goroutine都结束

    end := time.Since(start)
    fmt.Println("选择样机 0" + strconv.Itoa(template) + ".jpg 共生成 " + strconv.Itoa(len(picList)) + " 图片,耗时:", end)
}

/**
* @param baseTpl 模板
* @param outDir 保存路径
* @param sourcePic 源文件
 */
func template1(baseTpl, outDir, sourcePic string) {
    defer wg.Done() // goroutine结束就登记-1
    templateFile, err := os.Open(baseTpl)
    if err != nil {
        panic(err)
    }
    defer templateFile.Close()
    // 解码
    templateFileImage, err := jpeg.Decode(templateFile)
    if err != nil {
        panic(err)
    }
    // 新建一张和模板文件一样大小的画布
    newTemplateImage := image.NewRGBA(templateFileImage.Bounds())
    // 将模板图片画到新建的画布上
    draw.Draw(newTemplateImage, templateFileImage.Bounds(), templateFileImage, templateFileImage.Bounds().Min, draw.Over)

    // ====================向模板中粘贴图片 begin========================
    imageData, err := getDataByImage(sourcePic)
    if err != nil {
        fmt.Println("获取图片失败,err:", err.Error())
        return
    }


    //2、重新调整要粘贴图片尺寸
    imageData = resize.Resize(575, 431, imageData, resize.Lanczos3)
    //     粘贴缩略图
    draw.Draw(newTemplateImage,
        newTemplateImage.Bounds().Add(image.Pt(366, 74)),
        imageData,
        imageData.Bounds().Min,
        draw.Over)

    imageData = resize.Resize(600, 450, imageData, resize.Lanczos3)
    //     粘贴缩略图
    draw.Draw(newTemplateImage,
        newTemplateImage.Bounds().Add(image.Pt(106, 956)),
        imageData,
        imageData.Bounds().Min,
        draw.Over)


    imageData = resize.Resize(1024, 916, imageData, resize.Lanczos3)
    //     粘贴缩略图
    draw.Draw(newTemplateImage,
        newTemplateImage.Bounds().Add(image.Pt(0, 1779)),
        imageData,
        imageData.Bounds().Min,
        draw.Over)

    _, fileName := filepath.Split(sourcePic)
    // ====================向模板中粘贴图片 结束========================
    // 保存图片  ---> 在此我们统一将文件保存到:
    outFile := strings.TrimRight(outDir, "\\")  + "\\" + fileName
    saveFile(newTemplateImage, outFile)
}

/**
* @param baseTpl 模板
* @param outDir 保存路径
* @param sourcePic 源文件
 */
func template2(baseTpl, outDir, sourcePic string) {
    defer wg.Done() // goroutine结束就登记-1
    templateFile, err := os.Open(baseTpl)
    if err != nil {
        panic(err)
    }
    defer templateFile.Close()
    // 解码
    templateFileImage, err := jpeg.Decode(templateFile)
    if err != nil {
        panic(err)
    }
    // 新建一张和模板文件一样大小的画布
    newTemplateImage := image.NewRGBA(templateFileImage.Bounds())
    // 将模板图片画到新建的画布上
    draw.Draw(newTemplateImage, templateFileImage.Bounds(), templateFileImage, templateFileImage.Bounds().Min, draw.Over)

    // ====================向模板中粘贴图片 begin========================
    imageData, err := getDataByImage(sourcePic)
    if err != nil {
        fmt.Println("获取图片失败,err:", err.Error())
        return
    }


    //2、重新调整要粘贴图片尺寸
    imageData = resize.Resize(760, 760, imageData, resize.Lanczos3)
    //     粘贴缩略图
    draw.Draw(newTemplateImage,
        newTemplateImage.Bounds().Add(image.Pt(134, 165)),
        imageData,
        imageData.Bounds().Min,
        draw.Over)

    imageData = resize.Resize(704, 704, imageData, resize.Lanczos3)
    //     粘贴缩略图
    draw.Draw(newTemplateImage,
        newTemplateImage.Bounds().Add(image.Pt(163, 1870)),
        imageData,
        imageData.Bounds().Min,
        draw.Over)


    imageData = resize.Resize(1024, 885, imageData, resize.Lanczos3)
    //     粘贴缩略图
    draw.Draw(newTemplateImage,
        newTemplateImage.Bounds().Add(image.Pt(0, 3407)),
        imageData,
        imageData.Bounds().Min,
        draw.Over)

    _, fileName := filepath.Split(sourcePic)
    // ====================向模板中粘贴图片 结束========================
    // 保存图片  ---> 在此我们统一将文件保存到:
    outFile := strings.TrimRight(outDir, "\\")  + "\\" + fileName
    saveFile(newTemplateImage, outFile)
}

/**
* @param baseTpl 模板
* @param outDir 保存路径
* @param sourcePic 源文件
 */
func template3(baseTpl, outDir, sourcePic string) {
    defer wg.Done() // goroutine结束就登记-1
    templateFile, err := os.Open(baseTpl)
    if err != nil {
        panic(err)
    }
    defer templateFile.Close()
    // 解码
    templateFileImage, err := jpeg.Decode(templateFile)
    if err != nil {
        panic(err)
    }
    // 新建一张和模板文件一样大小的画布
    newTemplateImage := image.NewRGBA(templateFileImage.Bounds())
    // 将模板图片画到新建的画布上
    draw.Draw(newTemplateImage, templateFileImage.Bounds(), templateFileImage, templateFileImage.Bounds().Min, draw.Over)

    // ====================向模板中粘贴图片 begin========================
    imageData, err := getDataByImage(sourcePic)
    if err != nil {
        fmt.Println("获取图片失败,err:", err.Error())
        return
    }


    //2、重新调整要粘贴图片尺寸
    imageData = resize.Resize(1606, 2273, imageData, resize.Lanczos3)
    //     粘贴缩略图
    draw.Draw(newTemplateImage,
        newTemplateImage.Bounds().Add(image.Pt(150, 103)),
        imageData,
        imageData.Bounds().Min,
        draw.Over)

    imageData = resize.Resize(1095, 1549, imageData, resize.Lanczos3)
    //     粘贴缩略图
    draw.Draw(newTemplateImage,
        newTemplateImage.Bounds().Add(image.Pt(575, 3611)),
        imageData,
        imageData.Bounds().Min,
        draw.Over)


    imageData = resize.Resize(970, 1373, imageData, resize.Lanczos3)
    //     粘贴缩略图
    draw.Draw(newTemplateImage,
        newTemplateImage.Bounds().Add(image.Pt(227, 6778)),
        imageData,
        imageData.Bounds().Min,
        draw.Over)

    _, fileName := filepath.Split(sourcePic)
    // ====================向模板中粘贴图片 结束========================
    // 保存图片  ---> 在此我们统一将文件保存到:
    outFile := strings.TrimRight(outDir, "\\")  + "\\" + fileName
    saveFile(newTemplateImage, outFile)
}


//获取指定目录下的所有文件,包含子目录下的文件
func GetAllFiles(dirPth string, suffixList []string) (files []string, err error) {
    var dirs []string
    dir, err := ioutil.ReadDir(dirPth)
    if err != nil {
        return nil, err
    }

    PthSep := string(os.PathSeparator)

    for _, fi := range dir {
        if fi.IsDir() { // 目录, 递归遍历
            dirs = append(dirs, dirPth+PthSep+fi.Name())
            GetAllFiles(dirPth + PthSep + fi.Name(), suffixList)
        } else {
            // 过滤指定格式
            for _, suffix := range suffixList {
                fileName := strings.ToLower(fi.Name())
                ok := strings.HasSuffix(fileName, suffix)
                if ok {
                    files = append(files, dirPth+PthSep+fi.Name())
                }
            }
        }
    }

    // 读取子目录下文件
    for _, table := range dirs {
        temp, _ := GetAllFiles(table, suffixList)
        for _, temp1 := range temp {
            files = append(files, temp1)
        }
    }

    return files, nil
}

// 根据地址获取图片内容
func getDataByImage(picUrl string) (img image.Image, err error) {
    if !strings.HasPrefix(picUrl, ".jpg") &&
        !strings.HasPrefix(picUrl, ".jpeg") &&
        !strings.HasPrefix(picUrl, ".jpg") {
        err = fmt.Errorf("[%s]不支持的图片类型,暂只支持.jpg、.png文件类型", picUrl)
    }

    fp, err := os.Open(picUrl)
    if err != nil {
        return nil, err
    }
    defer fp.Close()

    // 解码图片
    if strings.HasSuffix(picUrl, ".jpg") || strings.HasSuffix(picUrl, ".jpeg") {
        img, err = jpeg.Decode(fp)
        if err != nil {
            return nil, err
        }
    }

    if strings.HasSuffix(picUrl, ".png") {
        img, err = png.Decode(fp)
        if err != nil {
            err = fmt.Errorf("png.Decode err:%s", err.Error())
            return nil, err
        }
    }

    return img, nil
}

func saveFile(pic *image.RGBA, outFile string) {
    dstFile, err := os.Create(outFile)
    if err != nil {
        fmt.Println(err)
    }
    defer dstFile.Close()
    err = jpeg.Encode(dstFile, pic, nil)
    if err != nil {
        panic(err)
    }
}
/**
* 判断目录是否存
 */
func PathExists(path string) (bool, error) {
    _, err := os.Stat(path)
    if err == nil {
        return true, nil
    }
    if os.IsNotExist(err) {
        return false, nil
    }
    return false, err
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值