在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 相关文章推荐
10种检测Python程序运行时间、CPU和内存占用的方法
Apr 01 Python
TensorFlow实现AutoEncoder自编码器
Mar 09 Python
python topN 取最大的N个数或最小的N个数方法
Jun 04 Python
Python实现正则表达式匹配任意的邮箱方法
Dec 20 Python
Python 给屏幕打印信息加上颜色的实现方法
Apr 24 Python
Python爬虫动态ip代理防止被封的方法
Jul 07 Python
如何安装并使用conda指令管理python环境
Jul 10 Python
python 解决cv2绘制中文乱码问题
Dec 23 Python
django 读取图片到页面实例
Mar 27 Python
在django中实现choices字段获取对应字段值
Jul 12 Python
python必学知识之文件操作(建议收藏)
May 30 Python
基于Python实现一个春节倒计时脚本
Jan 22 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
使用apache模块rewrite_module (转)
2007/02/14 PHP
PHP5中使用PDO连接数据库的方法
2010/08/01 PHP
批量修改RAR文件注释的php代码
2010/11/20 PHP
简单谈谈PHP中的include、include_once、require以及require_once语句
2016/04/23 PHP
PHP文件管理之实现网盘及压缩包的功能操作
2017/09/20 PHP
php+mysql开发的最简单在线题库(在线做题系统)完整案例
2019/03/30 PHP
PHP面向对象程序设计__tostring()和__invoke()用法分析
2019/06/12 PHP
TNC vs BOOM BO3 第一场2.13
2021/03/10 DOTA
jQuery的三种$()
2009/12/30 Javascript
Javascript自定义函数判断网站访问类型是PC还是移动终端
2014/01/10 Javascript
JQuery表单验证插件EasyValidator用法分析
2014/11/15 Javascript
javascript简单实现图片预加载
2014/12/03 Javascript
JavaScript 对象字面量讲解
2016/06/06 Javascript
搭建简单的nodejs http服务器详解
2017/03/09 NodeJs
详解node字体压缩插件font-spider的用法
2018/09/28 Javascript
javascript实现数字时钟效果
2021/02/06 Javascript
[01:46]2020完美世界全国高校联赛秋季赛报名开启
2020/10/15 DOTA
Python内置数据类型详解
2014/08/18 Python
Python深入学习之特殊方法与多范式
2014/08/31 Python
20个常用Python运维库和模块
2018/02/12 Python
详解python3中的真值测试
2018/08/13 Python
python实现机器学习之元线性回归
2018/09/06 Python
浅谈python实现Google翻译PDF,解决换行的问题
2018/11/28 Python
Python实现的大数据分析操作系统日志功能示例
2019/02/11 Python
Python基础学习之基本数据结构详解【数字、字符串、列表、元组、集合、字典】
2019/06/18 Python
django正续或者倒序查库实例
2020/05/19 Python
python中if及if-else如何使用
2020/06/02 Python
python调用jenkinsAPI构建jenkins,并传递参数的示例
2020/12/09 Python
详解基于canvas的视频遮罩插件
2018/01/04 HTML / CSS
澳大利亚个性化儿童礼品网站:Bright Star Kids
2019/06/14 全球购物
开业庆典主持词
2014/03/21 职场文书
房产授权委托书范本
2014/09/22 职场文书
慈善募捐倡议书
2015/04/27 职场文书
签证工作证明模板
2015/06/15 职场文书
公司团队口号霸气押韵
2015/12/24 职场文书
高中16字霸气押韵班级口号集锦!
2019/06/27 职场文书