在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生成pdf文件的方法
Aug 04 Python
python相似模块用例
Mar 04 Python
详解Python读取配置文件模块ConfigParser
May 11 Python
python算法演练_One Rule 算法(详解)
May 17 Python
python xlsxwriter库生成图表的应用示例
Mar 16 Python
Tensorflow卷积神经网络实例
May 24 Python
Django中日期处理注意事项与自定义时间格式转换详解
Aug 06 Python
Python 移动光标位置的方法
Jan 20 Python
numpy ndarray 取出满足特定条件的某些行实例
Dec 05 Python
Python中使用socks5设置全局代理的方法示例
Apr 15 Python
Python xpath表达式如何实现数据处理
Jun 13 Python
10张动图学会python循环与递归问题
Feb 06 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
dedecms 批量提取第一张图片最为缩略图的代码(文章+软件)
2009/10/29 PHP
JS与PHP向函数传递可变参数的区别实例代码
2011/05/18 PHP
php面试实现反射注入的详细方法
2019/09/30 PHP
laravel框架查询数据集转为数组的两种方法
2019/10/10 PHP
PHP pthreads v3在centos7平台下的安装与配置操作方法
2020/02/21 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
2020/02/23 PHP
解决PhpStorm64不能启动的问题
2020/06/20 PHP
用htc组件制作windows选项卡
2007/01/13 Javascript
ext监听事件方法[初级篇]
2008/04/27 Javascript
js form 验证函数 当前比较流行的错误提示
2009/06/23 Javascript
js动画(animate)简单引擎代码示例
2012/12/04 Javascript
浅谈JS日期(Date)处理函数
2014/12/07 Javascript
jQuery EasyUI 获取tabs的实例解析
2016/12/06 Javascript
jQuery插件HighCharts绘制2D饼图效果示例【附demo源码下载】
2017/03/21 jQuery
layui弹出层效果实现代码
2017/05/19 Javascript
js自定义弹框插件的封装
2020/08/24 Javascript
react-native中ListView组件点击跳转的方法示例
2017/09/30 Javascript
封装运动框架实战左右与上下滑动的焦点轮播图(实例)
2017/10/17 Javascript
react-router v4如何使用history控制路由跳转详解
2018/01/09 Javascript
vue2.0实现前端星星评分功能组件实例代码
2018/02/12 Javascript
在Vue项目中使用jsencrypt.js对数据进行加密传输的方法
2019/04/17 Javascript
原生JS实现留言板功能
2020/02/08 Javascript
在Python的Django框架中显示对象子集的方法
2015/07/21 Python
浅谈PYTHON 关于文件的操作
2019/03/19 Python
Python实现字符型图片验证码识别完整过程详解
2019/05/10 Python
适合Python初学者的一些编程技巧
2020/02/12 Python
python实现AHP算法的方法实例(层次分析法)
2020/09/09 Python
英国珠宝网站Argento: PANDORA、Olivia Burton和Nomination等
2020/05/08 全球购物
倡导文明标语
2014/06/16 职场文书
宾馆仓管员岗位职责
2014/07/27 职场文书
自我管理的活动方案
2014/08/25 职场文书
弘扬焦裕禄精神践行三严三实心得体会
2014/10/13 职场文书
环卫工作汇报材料
2014/10/28 职场文书
2014年专项整治工作总结
2014/11/17 职场文书
Python如何使用logging为Flask增加logid
2021/03/30 Python
python基础之错误和异常处理
2021/10/24 Python