自動化縮圖與生成文章檔案
在了解了縮圖對於照片的影響,以及Imagemagick的使用方法,我們現在將這些資訊實用化,應用在網路文章的寫作,我的目標有以下幾個:
- 將滑鼠點擊的次數降到最低。
- 跨平台的可能性。
- 未來應用的擴充性。
- 方便性。
這裡筆者以python程式進行上述目標的實作,請先去Imagemagick [1]網站下載convert套件並安裝好,確定他可以執行如下的縮圖指令
convert 原始圖檔.jpg -colorspace RGB -filter LanczosSharp -distort Resize 800x800 -unsharp 1x0.55+1.5+0.002 -colorspace sRGB -border 10 -quality 100 縮圖檔名.jpg
接著下載並安裝筆者的jpg2rst套件:
git clone https://github.com/sophAi/jpg2rst.git jpg2rst cd jpg2rst sudo easy_install *.egg
工作流程如下:
- 把想要縮圖的照片集中在一個目錄下。
- 執行jpg2rst.main()。
- 自動產生所有照片的縮圖到對應解析度的目錄下。
- 同時生成包含照片路徑的文件檔,這裡我們採用reStructuredText(ReST)格式。
這個檔案總共包含4個py檔,分別執行不同的工作,例如:
#!/usr/bin/env python def search(keyword='.jpg',recursive='n'): ''' Search for the files (default=.jpg) in the current or the subdirectories and return a list of the full paths. return: file_list (str list) usage: search_file(str keyword,str recursive) example: search_file(keyword='*.jpg',recursive='y') recursive: 'y' # turn on the recursive searching in the subdirectories''' import os from fnmatch import fnmatch file_list = list() if recursive == 'y': for root, dirs, files in os.walk('.'): for file_name in files: if fnmatch(os.path.join(root, file_name).lower().lstrip('./'),keyword.lower()): file_list.append(os.path.join(root,file_name).lstrip('./')) #Using walk, the file name would start with './dir/file.dat'. Use lstrip('./') to remove the string. else: for file_name in os.listdir('.'): if fnmatch(file_name.lower().lstrip('./'),keyword.lower()): file_list.append(file_name) file_list.sort() return file_list def clear(file_list): ''' Delete the files by the file_list. Use search() first to determine the file_list''' import os if type(file_list).__name__ == 'str': print('Delete '+file_list) os.remove(file_list) elif tpye(file_list).__name__ == 'list': for file_name in file_list: print('Delete '+file_name) os.remove(file_name) def copy(file_list,destinate_list='.'): ''' Copy the files listed in the file_list to the destinate_list. Use search() first to determine the file_list. destinate_list may be a string(dir_path) or a list of full paths To copy the file to the current directory, specify '.' as the destinate_list''' import shutil, os, sys file_type = type(file_list).__name__ file_len = len(file_list) destinate_type = type(destinate_list).__name__ destinate_len = len(destinate_list) if file_list != destinate_list: if file_type == 'list' and destinate_type == 'list' and file_len == destinate_len: I0=0 for file_name in file_list: print('Copy '+file_name+' to '+destinate_list[I0]) shutil.copy(file_name,destinate_list[I0]) I0=I0+1 elif file_type == 'list' and destinate_type == 'str' and os.path.isdir(destinate_list): # A list of files copied to a directory for file_name in file_list: print('Copy '+file_name+' to '+destinate_list) shutil.copy(file_name,destinate_list) elif file_type == 'str' and destinate_type == 'str': # Copy one file shutil.copy(file_list,destinate_list) elif file_type == 'str' and destinate_type == 'list': multi_target_opt = raw_input("Copy one file to multiple targets. Are you sure? (y/n)\n") if multi_target_opt == 'y': for target_file_name in destinate_list: print ('Copy '+ file_list+' to '+target_file_name) shutil.copy(file_list,target_file_name) else: print ("Error occurs!Exit!") sys.exit(1) def move(file_list,destinate_list='.'): ''' Move the files listed in the file_list to the destinate_list. Use searh() to determine the file_list''' print ('Copying files...') copy(file_list,destinate_list) remove_opt = raw_input('Delete the source files?(y/n)\n') if remove_opt == 'y': print('Deleting files...') clear(file_list) print('Moving files complete!') def main(): search() if __name__ == "__main__": main()
其主要的任務是搜尋當前以及所有子目錄下的特定檔案,如同search()開頭所述,我們只要指定keyword,他就會將符合特徵的檔案列表傳回,我們將會利用這個列表來進行縮圖以及生成文字範例檔的工作,search()的用途當然不只是在縮圖,日後可以非常方便的用他來做大量處理檔案的工作。
#!/usr/bin/env python def resize(resolution,jpg_list): ''' Input the resolution referring to the maximal height and width of the resizing jpg files Return: resize_jpg_list (str list) Usage: resize_jpg(str/int/str_list resolution, str_list jpg_list) Example: resize_jpg(resolution=['640','800'],jpg_list=[]) Resolution can be either integer, string, or a list of strings''' import subprocess, string, sys, os, shutil resize_jpg_list=list() if type(resolution).__name__ == 'int': resize_res_list=[str(resolution)] elif type(resolution).__name__ == 'str': resize_res_list=[resolution] elif type(resolution).__name__ == 'list': resize_res_list=resolution for resize_res in resize_res_list: if os.path.isdir(resize_res): print (resize_res+'/'+" directory exist! Cleaning it\n") shutil.rmtree(resize_res) print ("Making new directory: "+resize_res+'/ \n') os.mkdir(resize_res) for file_name in jpg_list: if file_name.find(resolution+'_') == -1: #Detect existing resized jpg file resize_file_name=file_name.split('/')[0:-1] resize_file_name.append(resize_res+'/'+resize_res+'_'+file_name.split('/')[-1]) resize_file_name = string.join(resize_file_name,'/') convert_command=['convert',file_name,'-colorspace','RGB','-filter','LanczosSharp','-distort','Resize',resize_res+'x'+resize_res,'-unsharp','1x0.55+1.5+0.002','-colorspace','sRGB','-border','10','-quality','95',resize_file_name] print(" ".join(convert_command)+"\n") cmd_status = subprocess.call(convert_command) if cmd_status != 0: print('Subprocess.call failure! Exit now!\n') sys.exit(1) resize_jpg_list.append(resize_file_name) resize_jpg_list.sort() return resize_jpg_list def log(log_file,jpg_list): ''' Write a list of jpg file names to a log file Return: none Usage: fig_log(str log_file, str_list/str jpg_list) Example: fig_log(log_file='fig_list.log',jpg_list)''' import os log_file_obj = open(log_file,'w') if type(jpg_list).__name__ == 'str': file_list = [jpg_list] elif type(jpg_list).__name__ == 'list': file_list = jpg_list for file_name in file_list: log_file_obj.write(file_name+'\n') log_file_obj.close() print('Write log file to '+log_file+'\n') def main(): resize() if __name__ == "__main__": main()
有了search()傳回的檔案列表,我們將其輸入至resize()這個函式裡,並指定圖形長與寬最大的解析度(例如800),他會偵測並將縮圖輸出到一個新的目錄(800/),同時也會自動略過已經縮圖過的圖檔,如果解析度的部份輸入none,則不會進行縮圖銳化的工作。
#!/usr/bin/env python def add_fig(fig_list): '''Form a template file in reST format and add the codes with the resized figures return rst_file (str), fig_num (int) usage: form_rst(str_list fig_list) example: form_rst(['fig1.jpg','fig2.jpg',...])''' import os import time from fnmatch import fnmatch time_label = time.strftime('%Y%m%d %H:%M:%S',time.localtime()) try: rst_temp_file_obj = open('/'+os.getcwd().split('/')[1]+'/'+os.getcwd().split('/')[2]+'/.vim/template/temp_rst.txt','r') rst_slug = os.getcwd().split('/')[-1] rst_file = rst_slug+'.rst' jpg2rst_temp_file_obj = open(rst_file,'w') line_info = rst_temp_file_obj.readline() while line_info != '.\n': line_info = rst_temp_file_obj.readline() if fnmatch(line_info,'*slug:*'): jpg2rst_temp_file_obj.write('.. slug: '+rst_slug+'\n') elif fnmatch(line_info,'*data:*'): jpg2rst_temp_file_obj.write('.. data: '+time_label+'\n') elif fnmatch(line_info,'*description:*'): jpg2rst_temp_file_obj.write('.. description: Created at '+time_label+'\n') elif fnmatch(line_info,'*<body>*'): #Insert codes of resized figure here jpg2rst_temp_file_obj.write(line_info) fig_number = len(fig_list) for rst_figure in fig_list: jpg2rst_temp_file_obj.write('\n.. figure:: '+rst_figure+'\n') jpg2rst_temp_file_obj.write(' :target: '+rst_figure+'\n') jpg2rst_temp_file_obj.write(' :align: center\n\n\n\n') # jpg2rst_temp_file_obj.write(' :width: 640'+'\n\n') elif line_info == '.\n': print('\nMake '+rst_file+' complete\n') else: jpg2rst_temp_file_obj.write(line_info) finally: jpg2rst_temp_file_obj.close() rst_temp_file_obj.close() return rst_file def main(): add_fig() if __name__ == "__main__": main()
resize()會輸出縮圖銳化後的檔案列表,我們可以進一步將其輸入到add_fig()函式裡,他會自動擷取vim的ReST範例檔,並且將所有縮圖的圖片連結加進去,例如
.. figure:: ../gallaries/640/640_01_P1370103_sharpen.jpg :target: ../gallaries/640/640_01_P1370103_sharpen.jpg :align: center
由於search()會自動依照檔案名稱排序,一個小技巧就是於檔名開頭加上01、02、03...等編號。
您可以將ReST範例檔儲存在~/.vim/template/temp_rst.txt檔案裡,有關vim的自動文件範例檔筆者會另外說明,簡單來說,他可以偵測您創造的文字檔是屬於哪種格式(C++, Python, Latex...等),然後利用對應的範例檔生成文件,是個非常強大且高效率的功能。
最後是jpg2rst.py這個程式,其實就是用來整合上面3個函式,讓我們的工作流程得以實現,裏面有些目錄的設定,可以依照需求修改;不難發現,任何一個函式都可以獨立運作,例如我們可以單獨使用resize()來測試縮圖銳化的參數,也可以用search()來蒐集任何檔案,或是用add_fig()來重整文章的圖片連結,除了幫我們省去不少縮圖銳化的功夫,更可以在其餘工作裡派上用場,等於是辛苦一次受用無窮的工具,當我們不斷進行例行性的操作時,一個良好的自動化工具可以大大提高工作效率,讓我們有更多時間陪陪家人,或是喝杯咖啡思考一下。
[1] | http://www.imagemagick.org/script/binary-releases.php#iOS |
Comments
Comments powered by Disqus