在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 相关文章推荐
Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法
May 22 Python
python安装mysql-python简明笔记(ubuntu环境)
Jun 25 Python
Python遍历目录中的所有文件的方法
Jul 08 Python
python爬虫实战之最简单的网页爬虫教程
Aug 13 Python
Python3中类、模块、错误与异常、文件的简易教程
Nov 20 Python
Python操作Oracle数据库的简单方法和封装类实例
May 07 Python
详解Python:面向对象编程
Apr 10 Python
Apache部署Django项目图文详解
Jul 30 Python
python GUI库图形界面开发之PyQt5线程类QThread详细使用方法
Feb 26 Python
Android Q之气泡弹窗的实现示例
Jun 23 Python
Python headers请求头如何实现快速添加
Nov 03 Python
python实现进度条的多种实现
Apr 29 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网站基础优化方法小结
2008/09/29 PHP
smarty的保留变量问题
2008/10/23 PHP
php使用google地图应用实例
2014/12/31 PHP
php比较相似字符串的方法
2015/06/05 PHP
jquery操作select option 的代码小结
2011/06/21 Javascript
JavaScript 封装一个tab效果源码分享
2015/09/15 Javascript
JavaScript制作简单分页插件
2016/09/11 Javascript
Node.js的环境安装配置(使用nvm方式)
2016/10/11 Javascript
微信小程序  checkbox组件详解及简单实例
2017/01/10 Javascript
JS+jQuery实现注册信息的验证功能
2017/09/26 jQuery
AngularJS实现图片上传和预览功能的方法分析
2017/11/08 Javascript
纯js封装的ajax功能函数与用法示例
2018/05/14 Javascript
微信小程序实现的一键连接wifi功能示例
2019/04/24 Javascript
详解async/await 异步应用的常用场景
2019/05/13 Javascript
layui给下拉框、按钮状态、时间赋初始值的方法
2019/09/10 Javascript
nodejs的安装使用与npm的介绍
2019/09/11 NodeJs
vue data变量相互赋值后被实时同步的解决步骤
2020/08/05 Javascript
[04:53]DOTA2英雄基础教程 祈求者
2014/01/03 DOTA
Python 实现 贪吃蛇大作战 代码分享
2016/09/07 Python
python+matplotlib演示电偶极子实例代码
2018/01/12 Python
使用浏览器访问python写的服务器程序
2019/10/10 Python
Python如何实现在字符串里嵌入双引号或者单引号
2020/03/02 Python
在python中list作函数形参,防止被实参修改的实现方法
2020/06/05 Python
Python-openCV开运算实例
2020/07/05 Python
浅析图片上传及canvas压缩的流程
2020/06/10 HTML / CSS
FC-Moto美国:欧洲最大的摩托车服装和头盔商店之一
2019/08/24 全球购物
中国京东和泰国中央集团合资的网站:JD CENTRAL
2020/08/22 全球购物
JAVA高级程序员面试题
2013/09/06 面试题
电子商务网站的创业计划书
2014/01/05 职场文书
物理专业本科生自荐信
2014/01/30 职场文书
给校长的建议书400字
2014/05/15 职场文书
关于工作经历的证明书
2014/10/11 职场文书
回复函格式及范文
2015/07/14 职场文书
导游词之山东孔庙
2019/11/04 职场文书
Python使用BeautifulSoup4修改网页内容
2022/05/20 Python
Go Grpc Gateway兼容HTTP协议文档自动生成网关
2022/06/16 Golang