1. 程式人生 > >Python 批量修改圖片格式和尺寸

Python 批量修改圖片格式和尺寸

公司的一個專案要求把所有4096x4096的圖片全部轉化成2048x2048的圖片,這種批量轉換圖片大小的軟體網上很多,我的同事原來使用的美圖看看的批量轉換,但是稍微有點麻煩,每次還需要指定要轉換的圖片的輸入路徑和輸出路徑,而且每次都只能處理一個資料夾,很繁瑣,於是我想到了萬能的Python,然後寫了一個指令碼來批量處理圖片,同一個根目錄下的所有資料夾的子檔案等的圖片全部會處理掉。大笑

程式碼中還加入了很多的異常捕獲機制和提示,希望對大家有幫助。

備註:

1.匯入了PIL庫,是處理圖片用的,很強大;

2.匯入了win32庫,是判斷隱藏檔案用的,我們的專案需要刪除隱藏檔案,不需要的可以直接找到刪除。

3.匯入send2trash庫,是把刪除的檔案放進垃圾箱,而不是永久刪除,這個我只是防止刪除有用的檔案而搞得,有點嚴謹了是吧,不需要的可以刪掉啊。

4.我這個指令碼是Python2.7編寫的,但是在處理中文編碼的時候非常噁心,儘管最後被我解決了,這個解決的方法,我隨後會再單獨寫一篇,但是此刻我是建議大家不要用2.x版本的python 了。據說3.x的版本的已經解決了編碼的問題。希望大家聽我的建議。

#coding=utf-8
import sys
import os, glob
import platform
import win32file,win32con
from PIL import Image
from send2trash import send2trash

reload(sys)
sys.setdefaultencoding('utf-8')

#new_width =2048
#width =int(raw_input("the width U want:"))
#imgslist = glob.glob(path+'/*.*')

ShuiPing="水平"
ShiZhuang="矢狀"
GuanZhuang="冠狀"

def Py_Log(_string):
    print "----"+_string.decode('utf-8')+"----"

def is_windows_system():
    return 'Windows' in platform.system()

def is_hiden_file(file_Path): 
    if is_windows_system(): 
        fileAttr = win32file.GetFileAttributes(file_Path)
        if fileAttr & win32con.FILE_ATTRIBUTE_HIDDEN : 
            return True 
        return False 
    return False

def remove_hidden_file(file_path):
	send2trash(file_path)
	print "Delete hidden file path:"+file_path

def astrcmp(str1,str2):
    return str1.lower()==str2.lower()

def resize_image(img_path):
    try:
        mPath, ext = os.path.splitext(img_path)
        if (astrcmp(ext,".png") or astrcmp(ext,".jpg")):
            img = Image.open(img_path)
            (width,height) = img.size
            
            if(width != new_width):
                new_height = int(height * new_width / width)
                out = img.resize((new_width,new_height),Image.ANTIALIAS)
                new_file_name = '%s%s' %(mPath,ext)
                out.save(new_file_name,quality=100)
                Py_Log("圖片尺寸修改為:"+str(new_width))
            else:
                Py_Log("圖片尺寸正確,未修改")
        else:
            Py_Log("非圖片格式")
    except Exception,e:
        print e

#改變圖片型別
def change_img_type(img_path):
    try:
        img = Image.open(img_path)
        img.save('new_type.png')
    except Exception,e:
        print e

#處理遠端圖片
def handle_remote_img(img_url):
    try:
        request = urllib2.Request(img_url)
        img_data = urllib2.urlopen(request).read()
        img_buffer = StringIO.StringIO(img_data)
        img = Image.open(img_buffer)
        img.save('remote.jpg')
        (width,height) = img.size
        out = img.resize((200,height * 200 / width),Image.ANTIALIAS)
        out.save('remote_small.jpg')
    except Exception,e:
        print e

def rename_forder(forder_path):
    Py_Log("------------rename_forder--------------------------")
    names = os.path.split(forder_path)
    try:
        if(unicode(ShuiPing) in unicode(names[1],'gbk')):
            os.rename(forder_path,names[0]+"\\"+"01")
            Py_Log(names[1]+"-->"+"01")
        if(unicode(ShiZhuang) in unicode(names[1],'gbk')):
            os.rename(forder_path,names[0]+"\\"+"02")
            Py_Log(names[1]+"-->"+"02")
        if(unicode(GuanZhuang) in unicode(names[1],'gbk')):
            os.rename(forder_path,names[0]+"\\"+"03")
            Py_Log(names[1]+"-->"+"03")
    except Exception,e:
        print e

def BFS_Dir(dirPath, dirCallback = None, fileCallback = None):
    queue = []
    ret = []
    queue.append(dirPath);
    while len(queue) > 0:
        tmp = queue.pop(0)
        if(os.path.isdir(tmp)):
            ret.append(tmp)
            for item in os.listdir(tmp):
                queue.append(os.path.join(tmp, item))
            if dirCallback:
                dirCallback(tmp)
        elif(os.path.isfile(tmp)):
            ret.append(tmp)
            if fileCallback:
                fileCallback(tmp)
    return ret

def DFS_Dir(dirPath, dirCallback = None, fileCallback = None):
    stack = []
    ret = []
    stack.append(dirPath);
    while len(stack) > 0:
        tmp = stack.pop(len(stack) - 1)
        if(os.path.isdir(tmp)):
            ret.append(tmp)
            for item in os.listdir(tmp):
                stack.append(os.path.join(tmp, item))
            if dirCallback:
                dirCallback(tmp)
        elif(os.path.isfile(tmp)):
            ret.append(tmp)
            if fileCallback:
                fileCallback(tmp)
    return ret

def printDir(dirPath):
    print "dir: " + dirPath
    if(is_hiden_file(dirPath)):
        remove_hidden_file(dirPath)
    else:
        rename_forder(dirPath)

def printFile(dirPath):
    print "file: " + dirPath
    resize_image(dirPath)
    return True


if __name__ == '__main__':
    while True:
        path = raw_input("Path:")
        new_width =int(raw_input("the width U want:"))
        try:
            b = BFS_Dir(path , printDir, printFile)
            Py_Log ("\r\n          **********\r\n"+"*********圖片處理完畢*********"+"\r\n          **********\r\n")
        except:
            print "Unexpected error:", sys.exc_info()
        raw_input('press enter key to rehandle')