影刀RPA 图片处理基础:裁剪、缩放、水印
影刀RPA 图片处理基础裁剪、缩放、水印署名林焱什么情况用什么RPA采集商品数据时需要批量下载图片并统一尺寸截图后需要裁剪指定区域生成的报表图片需要加水印防盗用。场景推荐库特点基础裁剪/缩放/旋转PillowPIL轻量高效格式支持广批量加水印Pillow文字/图片水印均可图片拼接/合并Pillow多图拼接成一张怎么做一图片裁剪fromPILimportImage imgImage.open(rD:\图片\截图.png)# 裁剪指定区域 (left, upper, right, lower)croppedimg.crop((100,200,800,600))cropped.save(rD:\图片\裁剪后.png)# 裁剪居中区域width,heightimg.size crop_sizemin(width,height)# 取最小边做正方形left(width-crop_size)//2upper(height-crop_size)//2cropped_centerimg.crop((left,upper,leftcrop_size,uppercrop_size))cropped_center.save(rD:\图片\居中裁剪.png)二图片缩放fromPILimportImage imgImage.open(rD:\图片\原图.jpg)# 按固定尺寸缩放resizedimg.resize((800,600))resized.save(rD:\图片\缩放后.jpg)# 按比例缩放缩小到50%width,heightimg.size new_size(int(width*0.5),int(height*0.5))resizedimg.resize(new_size,Image.LANCZOS)# LANCZOS高质量缩放resized.save(rD:\图片\缩小50%.jpg)# 等比缩放限制最大宽度max_width400ifwidthmax_width:ratiomax_width/width new_size(max_width,int(height*ratio))resizedimg.resize(new_size,Image.LANCZOS)resized.save(rD:\图片\限宽400.jpg)三添加文字水印fromPILimportImage,ImageDraw,ImageFont imgImage.open(rD:\图片\产品图.jpg).convert(RGBA)# 创建透明图层overlayImage.new(RGBA,img.size,(0,0,0,0))drawImageDraw.Draw(overlay)# 加载字体指定中文字体路径try:fontImageFont.truetype(C:/Windows/Fonts/simhei.ttf,40)except:fontImageFont.load_default()# 绘制水印文字watermark_text林焱RPA# 半透明白色draw.text((50,50),watermark_text,fill(255,255,255,128),fontfont)# 合并图层resultImage.alpha_composite(img,overlay)result.convert(RGB).save(rD:\图片\加水印.jpg,quality95)四平铺水印fromPILimportImage,ImageDraw,ImageFontimportmath imgImage.open(rD:\图片\产品图.jpg).convert(RGBA)overlayImage.new(RGBA,img.size,(0,0,0,0))drawImageDraw.Draw(overlay)fontImageFont.truetype(C:/Windows/Fonts/simhei.ttf,36)# 平铺水印text内部使用 # 计算文字宽度bboxdraw.textbbox((0,0),text,fontfont)text_widthbbox[2]-bbox[0]text_heightbbox[3]-bbox[1]# 旋转45度的水印angle45foryinrange(-img.height,img.height,150):forxinrange(-img.width,img.width,int(text_width)80):draw.text((x,y),text,fill(255,255,255,60),fontfont)# 旋转整个水印层overlayoverlay.rotate(angle,expandFalse,center(img.width//2,img.height//2))resultImage.alpha_composite(img,overlay)result.convert(RGB).save(rD:\图片\平铺水印.jpg,quality95)五批量处理fromPILimportImageimportosimportglob# yd_input: input_dir, output_dir, target_width, qualityinput_diryd_input.get(input_dir,rD:\图片\原始)output_diryd_input.get(output_dir,rD:\图片\处理后)target_widthyd_input.get(target_width,800)qualityyd_input.get(quality,85)os.makedirs(output_dir,exist_okTrue)filesglob.glob(os.path.join(input_dir,*.jpg))\ glob.glob(os.path.join(input_dir,*.png))\ glob.glob(os.path.join(input_dir,*.jpeg))success0errors[]forfileinfiles:try:imgImage.open(file)# 统一转为RGB去掉alpha通道ifimg.modeRGBA:imgimg.convert(RGB)elifimg.mode!RGB:imgimg.convert(RGB)# 等比缩放width,heightimg.sizeifwidthtarget_width:ratiotarget_width/width new_heightint(height*ratio)imgimg.resize((target_width,new_height),Image.LANCZOS)# 保存basenameos.path.splitext(os.path.basename(file))[0]output_pathos.path.join(output_dir,f{basename}.jpg)img.save(output_path,JPEG,qualityquality)success1exceptExceptionase:errors.append(f{os.path.basename(file)}:{e})yd_output{status:ok,success:success,errors:errors,total:len(files)}有什么坑坑一RGBA图片保存为JPEG报错现象处理PNG透明图片时保存为JPEG报错cannot write mode RGBA as JPEG。原因JPEG不支持透明通道AlphaPNG的RGBA模式直接保存JPEG会报错。解决先转成RGBimgImage.open(透明图.png)# 转成RGB去掉透明通道透明区域变白ifimg.modein(RGBA,LA):backgroundImage.new(RGB,img.size,(255,255,255))background.paste(img,maskimg.split()[-1])# 用alpha通道做maskimgbackground img.save(输出.jpg,JPEG,quality95)# 或者简单转换透明区域变黑# img img.convert(RGB)坑二中文字体路径找不到现象ImageFont.truetype报OSError: cannot open resource。原因字体路径不对或者系统没有该字体。解决用系统中存在的字体加try-catchfromPILimportImageFontdefget_font(size30):获取可用中文字体font_paths[C:/Windows/Fonts/simhei.ttf,# 黑体C:/Windows/Fonts/msyh.ttc,# 微软雅黑C:/Windows/Fonts/simsun.ttc,# 宋体C:/Windows/Fonts/Deng.ttf,# 等线]forpathinfont_paths:try:returnImageFont.truetype(path,size)except:continuereturnImageFont.load_default()# 回退默认字体fontget_font(40)坑三图片旋转后尺寸变化现象旋转图片后发现图片变大了多了黑色边角。原因rotate默认expandFalse不扩展画布旋转后部分内容被裁掉。设expandTrue会扩展画布但多出黑色区域。解决# 方案1不扩展画布保持原尺寸裁掉超出部分rotatedimg.rotate(45,expandFalse)# 方案2扩展画布 填充背景色rotatedimg.rotate(45,expandTrue,fillcolor(255,255,255))# 方案3扩展画布 透明背景需要RGBA模式img_rgbaimg.convert(RGBA)rotatedimg_rgba.rotate(45,expandTrue)# rotated现在是RGBA透明背景坑四批量处理大图片内存溢出现象批量处理100张高分辨率照片每张10MB处理到一半内存不足。原因Pillow打开图片后不主动释放循环中累积。解决用with语句或手动closefromPILimportImageimportgcforfileinfiles:imgImage.open(file)# 处理...img.close()# 显式关闭gc.collect()# 可选强制垃圾回收# 或者用withforfileinfiles:withImage.open(file)asimg:imgimg.copy()# with退出后原文件句柄释放# 处理...