golang图片压缩
package main
import (
//"encoding/json"
"fmt"
//"os"
//"io/ioutil"
"github.com/nfnt/resize"
"image/jpeg"
"io"
"log"
"os"
"path/filepath"
"strconv"
// "flag"
"bufio"
"image"
"image/png"
"strings"
"time"
)
func imageCompress(
getReadSizeFile func() (io.Reader, error),
getDecodeFile func() (*os.File, error),
to string,
Quality,
base int,
format string) bool {
/** 读取文件 */
file_origin, err := getDecodeFile()
defer file_origin.Close()
if err != nil {
fmt.Println("os.Open(file)错误")
log.Fatal(err)
return false
}
var origin image.Image
var config image.Config
var temp io.Reader
/** 读取尺寸 */
temp, err = getReadSizeFile()
if err != nil {
fmt.Println("os.Open(temp)")
log.Fatal(err)
return false
}
var typeImage int64
format = strings.ToLower(format)
/** jpg 格式 */
if format == "jpg" || format == "jpeg" {
typeImage = 1
origin, err = jpeg.Decode(file_origin)
if err != nil {
fmt.Println("jpeg.Decode(file_origin)")
log.Fatal(err)
return false
}
temp, err = getReadSizeFile()
if err != nil {
fmt.Println("os.Open(temp)")
log.Fatal(err)
return false
}
config, err = jpeg.DecodeConfig(temp)
if err != nil {
fmt.Println("jpeg.DecodeConfig(temp)")
return false
}
} else if format == "png" {
typeImage = 0
origin, err = png.Decode(file_origin)
if err != nil {
fmt.Println("png.Decode(file_origin)")
log.Fatal(err)
return false
}
temp, err = getReadSizeFile()
if err != nil {
fmt.Println("os.Open(temp)")
log.Fatal(err)
return false
}
config, err = png.DecodeConfig(temp)
if err != nil {
fmt.Println("png.DecodeConfig(temp)")
return false
}
}
/** 做等比缩放 */
width := uint(base) /** 基准 */
height := uint(base * config.Height / config.Width)
canvas := resize.Thumbnail(width, height, origin, resize.Lanczos3)
file_out, err := os.Create(to)
defer file_out.Close()
if err != nil {
log.Fatal(err)
return false
}
if typeImage == 0 {
err = png.Encode(file_out, canvas)
if err != nil {
fmt.Println("压缩图片失败")
return false
}
} else {
err = jpeg.Encode(file_out, canvas, &jpeg.Options{Quality})
if err != nil {
fmt.Println("压缩图片失败")
return false
}
}
return true
}
func getFilelist(path string) {
/** 创建输出目录 */
errC := os.MkdirAll(inputArgs.OutputPath, 0777)
if errC != nil {
fmt.Printf("%s", errC)
return
}
err := filepath.Walk(path, func(pathFound string, f os.FileInfo, err error) error {
if f == nil {
return err
}
if f.IsDir() { /** 是否是目录 */
return nil
}
// println(pathFound)
/** 找到一个文件 */
/** 判断是不是图片 */
localPath, format, _ := isPictureFormat(pathFound)
/** 随机数 */
t := time.Now()
millis := t.Nanosecond() /** 纳秒 */
outputPath := inputArgs.OutputPath + strconv.FormatInt(int64(millis), 10) + "." + format
if localPath != "" {
if !imageCompress(
func() (io.Reader, error) {
return os.Open(localPath)
},
func() (*os.File, error) {
return os.Open(localPath)
},
outputPath,
inputArgs.Quality,
inputArgs.Width,
format) {
fmt.Println("生成缩略图失败")
} else {
fmt.Println("生成缩略图成功 " + outputPath)
}
}
return nil
})
if err != nil {
fmt.Printf("输入的路径信息有误 %v\n", err)
}
}
/** 是否是图片 */
func isPictureFormat(path string) (string, string, string) {
temp := strings.Split(path, ".")
if len(temp) <= 1 {
return "", "", ""
}
mapRule := make(map[string]int64)
mapRule["jpg"] = 1
mapRule["png"] = 1
mapRule["jpeg"] = 1
// fmt.Println(temp[1]+"---")
/** 添加其他格式 */
if mapRule[temp[1]] == 1 {
println(temp[1])
return path, temp[1], temp[0]
} else {
return "", "", ""
}
}
func execute() {
/** 获取输入 */
//str := ""
//fmt.Scanln (&str) /** 不要使用 scanf,它不会并以一个新行结束输入 */
reader := bufio.NewReader(os.Stdin)
data, _, _ := reader.ReadLine()
/** 分割 */
strPice := strings.Split(string(data), " ") /** 空格 */
if len(strPice) < 3 {
fmt.Printf("输入有误,参数数量不足,请重新输入或退出程序:")
execute()
return
}
inputArgs.LocalPath = strPice[0]
inputArgs.Quality, _ = strconv.Atoi(strPice[1])
inputArgs.Width, _ = strconv.Atoi(strPice[2])
pathTemp, format, top := isPictureFormat(inputArgs.LocalPath)
if pathTemp == "" {
/** 目录 */
/** 如果输入目录,那么是批量 */
fmt.Println("开始批量压缩...")
rs := []rune(inputArgs.LocalPath)
end := len(rs)
substr := string(rs[end-1 : end])
if substr == "/" {
/** 有 / */
rs := []rune(inputArgs.LocalPath)
end := len(rs)
substr := string(rs[0 : end-1])
endIndex := strings.LastIndex(substr, "/")
inputArgs.OutputPath = string(rs[0:endIndex]) + "/LghImageCompress/"
} else {
endIndex := strings.LastIndex(inputArgs.LocalPath, "/")
inputArgs.OutputPath = string(rs[0:endIndex]) + "/LghImageCompress/"
}
getFilelist(inputArgs.LocalPath)
fmt.Println("图片保存在文件夹 " + inputArgs.OutputPath)
} else {
/** 单个 */
/** 如果输入文件,那么是单个,允许自定义路径 */
fmt.Println("开始单张压缩...") //C:\Users\lzq\Desktop\Apk.jpg 75 200
inputArgs.OutputPath = top + "_compress." + format
if !imageCompress(
func() (io.Reader, error) {
return os.Open(inputArgs.LocalPath)
},
func() (*os.File, error) {
return os.Open(inputArgs.LocalPath)
},
inputArgs.OutputPath,
inputArgs.Quality,
inputArgs.Width,
format) {
fmt.Println("生成缩略图失败")
} else {
fmt.Println("生成缩略图成功 " + inputArgs.OutputPath)
finish()
}
}
time.Sleep(5 * time.Minute) /** 如果不是自己点击退出,延时5分钟 */
}
func finish() {
fmt.Printf("继续输入进行压缩或者退出程序:")
execute()
}
func showTips() {
tips := []string{
"请输入文件夹或图片路径:",
"如果输入文件夹,那么该目录的图片将会被批量压缩;",
"如果是图片路径,那么将会被单独压缩处理。",
"例如:",
"C:/Users/lzq/Desktop/headImages/ 75 200",
"指桌面 headImages 文件夹,里面的图片质量压缩到75%,宽分辨率为200,高是等比例计算",
"C:/Users/lzq/Desktop/headImages/1.jpg 75 200",
"指桌面的 headImages 文件夹里面的 1.jpg 图片,质量压缩到75%,宽分辨率为200,高是等比例计算 ",
"请输入:"}
itemLen := len(tips)
for i := 0; i < itemLen; i++ {
if i == itemLen-1 {
fmt.Printf(tips[i])
} else {
fmt.Println(tips[i])
}
}
}
type InputArgs struct {
OutputPath string /** 输出目录 */
LocalPath string /** 输入的目录或文件路径 */
Quality int /** 质量 */
Width int /** 宽度尺寸,像素单位 */
Format string /** 格式 */
}
var inputArgs InputArgs
func main() {
showTips()
execute()
time.Sleep(5 * time.Minute) /** 如果不是自己点击退出,延时5分钟 */
}
golang图片压缩的更多相关文章
- Golang 编写的图片压缩程序,质量、尺寸压缩,批量、单张压缩
目录: 前序 效果图 简介 全部代码 前序: 接触 golang 不久,一直是边学边做,边总结,深深感到这门语言的魅力,等下要跟大家分享是最近项目 服务端 用到的图片压缩程序,我单独分离了出来,做成了 ...
- 三款不错的图片压缩上传插件(webuploader+localResizeIMG4+LUploader)
涉及到网页图片的交互,少不了图片的压缩上传,相关的插件有很多,相信大家都有用过,这里我就推荐三款,至于好处就仁者见仁喽: 1.名气最高的WebUploader,由Baidu FEX 团队开发,以H5为 ...
- 前端构建工具之gulp(一)「图片压缩」
前端构建工具之gulp(一)「图片压缩」 已经很久没有写过博客了,现下终于事情少了,开始写博吧 今天网站要做一些优化:图片压缩,资源合并等 以前一直使用百度的FIS工具,但是FIS还没有提供图片压缩的 ...
- gulp图片压缩
gulp图片压缩 网页性能优化,通常要处理图片,尤其图片量大的时候,更需要工具来批量处理,这里使用gulp,做个简单总结 image-resize压缩尺寸 var gulp = require('gu ...
- Android 图片压缩、照片选择、裁剪,上传、一整套图片解决方案
1.Android一整套图片解决方案 http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650820998&idx=1& ...
- Java中图片压缩处理
原文http://cuisuqiang.iteye.com/blog/2045855 整理文档,搜刮出一个Java做图片压缩的代码,稍微整理精简一下做下分享. 首先,要压缩的图片格式不能说动态图片,你 ...
- android 图片压缩
引用:http://104zz.iteye.com/blog/1694762 第一:我们先看下质量压缩方法: private Bitmap compressImage(Bitmap image) { ...
- HTML5 CANVAS 实现图片压缩和裁切
原文地址:http://leonshi.com/2015/10/31/html5-canvas-image-compress-crop/?utm_source=tuicool&utm_medi ...
- C# 图片压缩
/// <summary> /// 图片压缩方法 /// </summary> /// <param name="sF ...
随机推荐
- react基础篇四
列表 & Keys 渲染多个组件 你可以通过使用{}在JSX内构建一个元素集合 下面,我们使用Javascript中的map()方法遍历numbers数组.对数组中的每个元素返回<li& ...
- HDU_1517_博弈(巧妙规律)
A Multiplication Game Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...
- Bem命名
BEM思想 1. 什么是BEM: BEM:(Block块,Element元素,Modifier修饰符)一种命名规范, 其核心思想是将页面拆分成一个个独立的富有语义的块(blocks),从而使得团队在开 ...
- android studio: 为现有项目添加C++支持
刚开始创建项目的时候并没有勾选“include C++ support” 选项: 后期增加步骤: 1.拷贝已有支持C++项目的CMakeLists.txt文件到现有项目的app目录下: 2.在app/ ...
- PAT_A1123#Is It a Complete AVL Tree
Source: PAT A1123 Is It a Complete AVL Tree (30 分) Description: An AVL tree is a self-balancing bina ...
- Labview学习笔记(二)
一.编程基础 LABVIEW程序成为虚拟.仪器程序,简称VI,一个最基本的VI包括三个部分:前面板.程序框图和图标/连接端口. 1.前面板 在前面板窗口中,可以添加输入控件和显示控件,同时,可以用快捷 ...
- [MySQL优化案例]系列 — RAND()优化
众所周知,在MySQL中,如果直接 ORDER BY RAND() 的话,效率非常差,因为会多次执行.事实上,如果等值查询也是用 RAND() 的话也如此,我们先来看看下面这几个SQL的不同执行计划和 ...
- 布尔类型、操作符别名、C++函数、动态内存分配(new\delete)、引用(day02)
六 C++的布尔类型 bool类型是C++中基本类型,专门表示逻辑值:true/false bool在内存上占一个字节:1表示true,0表示false bool类型可以接收任意类型和表达式的结果,其 ...
- nyoj112-指数运算
指数运算时间限制:600 ms | 内存限制:65535 KB难度:2描述写一个程序实现指数运算 X^N.(1<X<10,0<N<20)输入输入包含多行数据 每行数据是两个 ...
- UOJ #214 合唱队形 (概率期望计数、DP、Min-Max容斥)
9个月的心头大恨终于切掉了!!!! 非常好的一道题,不知为何uoj上被点了70个差评. 题目链接: http://uoj.ac/problem/214 题目大意: 请自行阅读. 题解: 官方题解讲得相 ...