WebP图片制作GUI工具

WebP是Google近几年推出的新型网络图片格式,有静态和动态两种类型,其中静态webp比jpg和png的压缩率都要大,而且失真率接近于png,远胜于jpg,因为他支持8位的透明通道。而动态webp比gif好了不止一两点,gif只支持2位的透明通道,而且图片锯齿严重。OK,既然有这么牛逼的图片格式,我们当然要好好使用了,而且现在Android端有Facebook推出的Fresco框架完美支持,不仅静态还是动态。可惜,现在制作WebP的工具寥寥无几,更不用说动态WebP了,只能靠Google提供的命令行工具,但是对于批量图片转换,命令未免太长了,着实不方便,故写下了这篇文章。

为了三种开发系统(Mac OS X,Windows,Linux)都能使用,这次就使用wxPython做这个GUI程序吧,最后再用pyinstaller打包到各个平台,好了,废话不多说,上源代码,由于篇幅原因,这里只贴关键逻辑代码。

# -*- coding: utf-8 -*-
__author__ = 'linfuyuan'
import base_window
import wx
import os
import my_process as mp
import sys

reload(sys)
sys.setdefaultencoding("utf-8")
import platform
import codecs
import shutil


class MyDialog(base_window.MyDialog1):
    def __init__(self, parent):
        base_window.MyDialog1.__init__(self, parent)
        self.my_process_dlg = mp.MyProcess(None, self.onCancel)
        self.is_cancel = False
        self.env = platform.system()

    def on_choose_dir(self, event):
        file_wildcard = "*"
        dlg = wx.FileDialog(self, u"请选择图片目录",
                            os.getcwd(),
                            style=wx.OPEN | wx.MULTIPLE,
                            wildcard=file_wildcard)
        if dlg.ShowModal() == wx.ID_OK:
            file_names = dlg.GetPaths()
            for fn in file_names:
                self.m_listBox1.Append(fn)
                # self.pic_gallery.Add(wx.StaticText(self, -1, fn), 0, wx.ALIGN_LEFT)
        dlg.Destroy()
        pass

    def on_png_to_webp(self, event):
        items = self.m_listBox1.GetItems()
        if len(items) > 0 and self.lib_exist():
            command = 'lib_mac%simg2webp' % os.sep
            if self.env == 'Linux':
                command = 'lib_linux%simg2webp' % os.sep
            elif self.env == 'Windows':
                command = 'lib_windows%simg2webp.exe' % os.sep
            self.my_process_dlg.m_staticText3.SetLabel(u'处理中')
            self.my_process_dlg.m_button5.SetLabel(u'取消')
            self.is_cancel = False
            self.my_process_dlg.m_gauge1.SetRange(len(items))
            self.my_process_dlg.m_gauge1.SetValue(0)
            self.my_process_dlg.Show()
            count = 0
            dest_dir = '%s%shappy_webp' % (os.getcwd(), os.sep)
            if not os.path.exists(dest_dir):
                os.mkdir(dest_dir)
            tmp_dir = '%s%stmp' % (os.getcwd(), os.sep)
            if not os.path.exists(tmp_dir):
                os.mkdir(tmp_dir)
            for item in items:
                if not self.is_cancel:
                    filename = item[item.rindex(os.sep):]
                    shutil.copy(item, '%s%s' % (tmp_dir, os.sep))
                    os.system(
                        '%s %s%s%s -o %s%s%s.webp' % (
                            command, tmp_dir, os.sep, filename, dest_dir, os.sep,
                            item[item.rindex(os.sep) + 1:item.rindex('.')]))
                    os.remove('%s%s%s' % (tmp_dir, os.sep, filename))
                    count += 1
                    self.my_process_dlg.m_gauge1.SetValue(count)
                else:
                    break
            self.my_process_dlg.m_staticText3.SetLabel(u"输出路径:%s" % dest_dir)
            self.my_process_dlg.m_button5.SetLabel(u'完成')

    def on_webp_to_animate(self, event):
        items = self.m_listBox1.GetItems()
        if len(items) > 0 and self.lib_exist():
            command = 'lib_mac%swebpmux' % os.sep
            if self.env == 'Linux':
                command = 'lib_linux%swebpmux' % os.sep
            elif self.env == 'Windows':
                command = 'lib_windows%swebpmux' % os.sep
            self.my_process_dlg.m_staticText3.SetLabel(u'处理中')
            self.my_process_dlg.m_button5.SetLabel(u'取消')
            self.is_cancel = False
            self.my_process_dlg.m_gauge1.SetRange(len(items))
            self.my_process_dlg.m_gauge1.SetValue(0)
            self.my_process_dlg.Show()
            dest_dir = '%s%shappy_animate_webp' % (os.getcwd(), os.sep)
            gap = int(self.m_textCtrl1.GetValue())
            if not os.path.exists(dest_dir):
                os.mkdir(dest_dir)
            tmp_dir = '%s%stmp' % (os.getcwd(), os.sep)
            if not os.path.exists(tmp_dir):
                os.mkdir(tmp_dir)
            tmp_files = []
            for item in items:
                filename = item[item.rindex(os.sep):]
                shutil.copy(item, '%s%s' % (tmp_dir, os.sep))
                tmp_files.append('%s%s%s' % (tmp_dir, os.sep, filename))
                # webpmux -frame 1.webp +100 -frame 2.webp +100+50+50 -frame 3.webp +100+50+50+1+b -loop 10 -bgcolor 255,255,255,255 -o anim_container.webp
            os.system(
                '%s %s -o %s%sanimate.webp' % (command,
                                               ' '.join(['-frame %s +%d+0+0+1+b' % (x, gap) for x in tmp_files]),
                                               dest_dir,
                                               os.sep))
            for tf in tmp_files:
                os.remove(tf)
            self.my_process_dlg.m_gauge1.SetValue(len(items))
            self.my_process_dlg.m_staticText3.SetLabel(u"输出路径:%s" % dest_dir)
            self.my_process_dlg.m_button5.SetLabel(u'完成')

    def onClear(self, event):
        self.m_listBox1.Clear()

    def onCancel(self):
        self.is_cancel = True
        self.my_process_dlg.Close()

    def lib_exist(self):
        if self.env == 'Darwin':
            if not os.path.exists('lib_mac'):
                dlg = wx.MessageDialog(None,
                                       u"请到http://download.csdn.net/detail/xanxus46/9794013 下载并解压到%s下" % os.getcwd(),
                                       u"lib_mac/webp类库找不到")
                dlg.ShowModal()
                dlg.Destroy()
                return False
            else:
                return True
        elif self.env == 'Linux':
            if not os.path.exists('lib_linux'):
                dlg = wx.MessageDialog(None,
                                       u"请到http://download.csdn.net/detail/xanxus46/9793858 下载并解压到%s下" % os.getcwd(),
                                       u"lib_linux/webp类库找不到"
                                       )
                dlg.ShowModal()
                dlg.Destroy()
                return False
            else:
                return True
        elif self.env == 'Windows':
            if not os.path.exists('lib_windows'):
                dlg = wx.MessageDialog(None,
                                       u"请到http://download.csdn.net/detail/xanxus46/9794046 下载并解压到%s下" % os.getcwd(),
                                       u"lib_windows\\webp类库找不到")
                dlg.ShowModal()
                dlg.Destroy()
                return False
            else:
                return True
        else:
            return True

其余的可参考http://download.csdn.net/detail/xanxus46/9794411完整的代码

下面介绍一下用pyinstaller打包好的程序的使用方法吧

下载地址:

windows http://download.csdn.net/detail/xanxus46/9794351 

mac http://download.csdn.net/detail/xanxus46/9794400,程序是main.cpp不是main,两者运行当前目录不同~

linux 由于google提供的libwep二进制程序运行不了,需要编译源码,我就没弄了微笑

使用很简单,打开软件会看到主界面


点击选择图片,然后如果是需要png转webp则选择png图片,需要静态webp转动态webp则选择webp图片,填上每帧的时间间隔,可多选。点击清除可清除已选的所有图片。


注意,这里不要选文件名带有中文的图片,因为python自古以来的编码问题,你懂的,但路径中可以带中文,这没问题。转化过程中,可能会报错,最可能是libwebp工具包不在当前目录,这里提供几个下载地址,其他的自行百度到google开发者页面下载吧,需要番羽墙你也懂得。

libwebp工具包下载地址:

windows64位:http://download.csdn.net/detail/xanxus46/9794046

mac:http://download.csdn.net/detail/xanxus46/9794013,mac真心简单

linux:http://download.csdn.net/detail/xanxus46/9793858,这个在ubuntu12.04运行不了,需要重新编译源码,不过其他系统可以尝试一下

转化完成后,会在程序的当前目录产生两个文件夹,一个是png转webp的目录happy_webp,另一个是静态转动态的目录happy_animate_webp,文件名和原来一样,只是扩展名改成webp,如图


对于webp图片的查看,可以用chrome浏览器打开,毕竟是google自家的产品嘛。

在用windows的程序时,可能会出现什么windows imaging component找不到的错误,这时需要从微软官网上下载,http://www.microsoft.com/en-us/download/details.aspx?id=32,windows问题真不少,博主推荐大家用mac的程序,几乎不会有什么兼容性问题哈~

好了,程序介绍完毕,欢迎大家留言咨询~

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值