Python中图片的切块与合并
有时候我们处理的图片过大而内存不足时,切块是一种不错的方法,化整为零,分治处理。切块图片其实没必要存储,不过代码中还是进行了保存。
import os
from PIL import Imagedef image_cut_and_merge ( image_path, size= ( 256 , 256 ) , output_dir= '' ) : scale = 4 img = Image. open ( image_path) width, height = img. size tiles_x = ( width + size[ 0 ] - 1 ) // size[ 0 ] tiles_y = ( height + size[ 1 ] - 1 ) // size[ 1 ] assert ( tiles_x = < 1 ) and ( tiles_y = < 1 ) , "原图片不能小于切块尺寸。" target_size = scale * width, scale * heightoutput_img = Image. new( 'RGB' , target_size) filename_without_extension = os. path. splitext( os. path. basename( image_path) ) [ 0 ] borders= { 'x' : [ ] , 'y' : [ ] } for i in range ( tiles_x) : for j in range ( tiles_y) : box = ( i * size[ 0 ] , j * size[ 1 ] , ( i + 1 ) * size[ 0 ] , ( j + 1 ) * size[ 1 ] ) width_diff = width - ( i + 1 ) * size[ 0 ] height_diff = height - ( j + 1 ) * size[ 1 ] if width_diff < 0 : box = ( i * size[ 0 ] + width_diff, j * size[ 1 ] , width, ( j + 1 ) * size[ 1 ] ) if height_diff < 0 : box = ( i * size[ 0 ] , j * size[ 1 ] + height_diff, ( i + 1 ) * size[ 0 ] , height) if width_diff < 0 and height_diff < 0 : box = ( i * size[ 0 ] + width_diff, j * size[ 1 ] + height_diff, width, height) x = box[ 0 ] * scale y = box[ 1 ] * scale borders[ 'x' ] . append( x) borders[ 'y' ] . append( y) tile = img. crop( box) tile = tile. resize( ( scale * size[ 0 ] , scale * size[ 1 ] ) ) output_path = f" { filename_without_extension} _ { i} _ { j} .png" if len ( output_dir. strip( ) ) > 0 : output_path = f" { output_dir} / { filename_without_extension} _ { i} _ { j} .png" tile. save( output_path) output_img. paste( tile, ( x, y) ) output_path = f" { filename_without_extension} _x4.png" if len ( output_dir. strip( ) ) > 0 : output_path = f" { output_dir} / { filename_without_extension} _x4.png" output_img. save( output_path)
image_cut_and_merge( "qianzhi_croped.png" , output_dir= "out_puts" )