在Python中使用pngquant压缩png图片的教程


Posted in Python onApril 09, 2015

说到png图片压缩,可能很多人知道TinyPNG这个网站。但PS插件要钱(虽然有破解的),Developer API要连到他服务器去,不提网络传输速度,Key也是有每月限制的。
    
    但是貌似tinyPNG是使用了来自于 pngquant 的技术,至少在 http://pngquant.org/ 中是如此声称的:TinyPNG and Kraken.io — on-line interfaces for pngquant。如果真是这样,我很想对TinyPNG说呵呵。后者是开源的,连首页中提供的GUI工具也都是开源的。并且TinyPNG在首页的原理说明里面,一次都没提到pngquant

    我取了tinyPNG的首页上的示例图用pngquant命令行跑了一下,压缩率和显示效果差不多。

    pngquant首页上提供的工具中,Pngyu(http://nukesaq88.github.io/Pngyu/)是跨平台并且开源的,个人觉得已经相当好用了,直接把文件夹往里面拽就能递归处理,支持各种形式的生成方式(改名、覆盖、存储到其他目录等),压缩结束给出压缩比,并且还支持预览。

    但我还是会希望能够通过脚本来处理,一方面可定制性更强,一方面更方便整合到整个自动化的流程链中。于是我又拿出了python试图写点什么,谁知道……

    pngquant的命令行方式略坑……help中的参数说明和实际效果不一致,已经发现的问题有

    1. --force 参数无效,只要输出文件存在,就会报错,无视这个本用来指定覆写的参数
    2. --skip-if-larger 参数不正常,有时候生成文件明明比较小,也会被skip掉……

    不过好在python大法好,这些问题虽然命令行本身不能处理,但python可以在上层处理掉,下面就是目前实际使用的递归处理某文件夹png的脚本:

'''
pngquant.py
use pngquant to reduces png file size
Ruoqian, Chen<piao.polar@gmail.com> 

----------
2015/4/3
1. del option --quality=50-90, special pic need skip can config in lod ini

  lod ini format:

[PixelFormat]
map_01.png=0

  0 means skip in file

----------
2015/4/2
1. desDir can be the same to srcDir, or another dir
2. lod ini config can be not exist

----------
2015/3/31
create
'''

import os
import os.path
import sys
import ConfigParser
import string

PngquantExe="pngquant"

thisFilePath = sys.path[0];

print "this py file in dir : " + thisFilePath

projectPath = thisFilePath + "/../CMWar_2dx/CMWar_2dx/";
srcResDir = "Resources/";
dstResDir = "Resources/";

lodIniPath = projectPath + srcResDir + "ini/pic.ini"
keepOrgPaths = [];
if os.path.exists(lodIniPath):
  config = ConfigParser.SafeConfigParser()
  config.read(lodIniPath)
  section = "PixelFormat";
  options = config.options(section)
  for option in options:
    value = string.atoi(config.get(section, option))
    if not value:
      keepOrgPaths.append(option);

print keepOrgPaths

srcResPath = projectPath + srcResDir;

pngCount = 0;
transCount = 0;

#pngquant --force --skip-if-larger --ext .png --quality 50-90 --speed 1

for parent,dirnames,filenames in os.walk(srcResPath):
  print "----- process Dir " + parent
  dstDir = parent.replace(srcResDir, dstResDir)
  if not os.path.exists(dstDir):
    os.makedirs(dstDir)
  for filename in filenames:
    if os.path.splitext(filename)[1] == '.png':
      pngCount += 1;
      srcFilePath = os.path.join(parent, filename);
      dstFilePath = os.path.join(dstDir, filename);
      tmpFilePath = dstFilePath + ".tmp";

      if filename in keepOrgPaths:
        print "----- keep ----- " + filename;
      else:
#        print "----- process ----- " + filename;
#        cmd = "\"" + PngquantExe + "\"" + " --force --speed=1 --quality=50-90 -v " + srcFilePath + " -o " + tmpFilePath;
        cmd = "\"" + PngquantExe + "\"" + " --force --speed=1 " + srcFilePath + " -o " + tmpFilePath;
#        print cmd;
        os.system(cmd)
        if os.path.exists(tmpFilePath):
          sizeNew = os.path.getsize(tmpFilePath);
          sizeOld = os.path.getsize(srcFilePath);
          if sizeNew < sizeOld:
            open(dstFilePath, "wb").write(open(tmpFilePath, "rb").read())
            transCount += 1;
          os.remove(tmpFilePath)
      if not os.path.exists(dstFilePath):
        open(dstFilePath, "wb").write(open(srcFilePath, "rb").read())

print "Done. Trans Pngs: %d/%d" %(transCount, pngCount)

Python 相关文章推荐
python实现带验证码网站的自动登陆实现代码
Jan 12 Python
举例介绍Python中的25个隐藏特性
Mar 30 Python
python爬虫headers设置后无效的解决方法
Oct 21 Python
Java分治归并排序算法实例详解
Dec 12 Python
代码详解django中数据库设置
Jan 28 Python
解决pyqt5中QToolButton无法使用的问题
Jun 21 Python
python多进程下实现日志记录按时间分割
Jul 22 Python
Django1.11自带分页器paginator的使用方法
Oct 31 Python
如何解决安装python3.6.1失败
Jul 01 Python
Python数据可视化实现漏斗图过程图解
Jul 20 Python
python利用线程实现多任务
Sep 18 Python
通过实例解析python subprocess模块原理及用法
Oct 10 Python
python optparse模块使用实例
Apr 09 #Python
Python中处理时间的几种方法小结
Apr 09 #Python
Python CSV模块使用实例
Apr 09 #Python
Python常用随机数与随机字符串方法实例
Apr 09 #Python
在Python中使用CasperJS获取JS渲染生成的HTML内容的教程
Apr 09 #Python
举例讲解Python程序与系统shell交互的方式
Apr 09 #Python
使用Python中的cookielib模拟登录网站
Apr 09 #Python
You might like
解析php 版获取重定向后的地址(代码)
2013/06/26 PHP
WampServer搭建php环境时遇到的问题汇总
2015/07/23 PHP
详解PHP序列化反序列化的方法
2015/10/27 PHP
js中获取事件对象的方法小结
2011/03/13 Javascript
MooTools 页面滚动浮动层智能定位实现代码
2011/08/23 Javascript
js性能优化 如何更快速加载你的JavaScript页面
2012/03/17 Javascript
nodejs进阶(6)—连接MySQL数据库示例
2017/01/07 NodeJs
从零开始学习Node.js系列教程五:服务器监听方法示例
2017/04/13 Javascript
深入理解ES6学习笔记之块级作用域绑定
2017/08/19 Javascript
基于vue2实现上拉加载功能
2017/11/28 Javascript
vue指令只能输入正数并且只能输入一个小数点的方法
2018/06/08 Javascript
浅谈vux之x-input使用以及源码解读
2018/11/04 Javascript
8个有意思的JavaScript面试题
2019/07/30 Javascript
详解js中的几种常用设计模式
2020/07/16 Javascript
使用Python编写爬虫的基本模块及框架使用指南
2016/01/20 Python
python3使用urllib模块制作网络爬虫
2016/04/08 Python
Python进度条实时显示处理进度的示例代码
2018/01/30 Python
python使用筛选法计算小于给定数字的所有素数
2018/03/19 Python
解决Pycharm中import时无法识别自己写的程序方法
2018/05/18 Python
python+opencv实现霍夫变换检测直线
2020/10/23 Python
Python编程深度学习绘图库之matplotlib
2018/12/28 Python
Python OpenCV 调用摄像头并截图保存功能的实现代码
2019/07/02 Python
python实现批量修改服务器密码的方法
2019/08/13 Python
使用python去除图片白色像素的实例
2019/12/12 Python
Django实现任意文件上传(最简单的方法)
2020/06/03 Python
北京泡泡网网络有限公司.net面试题
2012/07/17 面试题
文员个人求职自荐信
2013/09/21 职场文书
80后职场人的职业生涯规划
2014/03/08 职场文书
珍爱生命演讲稿
2014/05/10 职场文书
有关环保的标语
2014/06/13 职场文书
公司年夜饭通知
2015/04/25 职场文书
党支部审查意见
2015/06/02 职场文书
《实心球》教学反思
2016/02/23 职场文书
go 原生http web 服务跨域restful api的写法介绍
2021/04/27 Golang
PyTorch中的torch.cat简单介绍
2022/03/17 Python
CentOS安装Nginx并部署vue
2022/04/12 Servers