在写Photoshop的打印操作之前,先来回顾下打印之前的图像处理工作。
接到的地质图多为MapGIS程序导出的jpg图片,偶尔也会有Tif格式的遥感图。对这些图像进行打印很简单,基本流程是:用PS打开图像->裁剪图像四周空白边缘->为图像四周加上3cm宽白色边框(为了美观和装订的需要)->打印。那为啥用PS来打印不直接用Windows自带打印呢,应该是打印需要用到PS特定的颜色处理模式吧,经过试验,通过两种方式打出来的色彩效果确实是不同的。
打印前图像处理的主要目标很简单:
1、裁剪图像四周空白
2、为图像四周加上3cm白色边框
下面就用Python实现它们
图像处理主要用的是PIL这个库,中途由于单位电脑比较旧(4g内存Win7 32位系统,后来重装成64位了,体验就是搞这种东西必须整个64位系统),性能不太行了,也用Opencv整了下,还是感觉PIL稍微快那么一点点,不知道是不是错觉呢。
(后来发现这两步在PS录个动作也能轻松完成(→ܫ←))
一、获取所有图片路径
有时候要打印的图片会放在好多个不同文件夹里面,要把它们遍历出来:
import os
二、读取图片并裁剪四周空白
import PIL
获得了图像尺寸后接下来就要对图像进行边缘空白的裁剪了(其实这两步不分先后顺序的):
裁剪的思路是网上搜到的,整理下就是:
1、先把图像转成灰度模式(值变成单一的0-255以方便判断,如果要裁剪其他颜色我就不知道了,我这里只要裁掉最常见的由MapGIS导出的标准的白色边缘)。
2、分别从四个方向扫描图像,找到四个方向各自第一个灰度值不为255(最纯粹的白色(→ܫ←))的像素,记下它的坐标(i,j)。
3、通过四组坐标大小比较,得到图像除了四周空白区域外的坐标极值,也就得到了裁剪的区域左上(left,top)和右下坐标(right,bottom)。
4、利用PIL.Image.crop(),完成图像的裁剪。
5、没了,就是后来发现PIL自带这个算法,引用一下: 使用PIL裁剪图片白边
要是用PS来做呢,‘图像-裁切-确定’就完事了。
三、给裁剪后的图像加上x厘米的白色边框
这一步主要是为了打印出来的图规范且美观。
这一步要是用PS来搞,‘图像-画布大小-设置相对的宽度和高度’ 就好了
四、判断图像是否需要旋转。
为什么要旋转这些图像呢?因为最终是要把它们用打印机打印出来,而打印机能打印的最大宽度是有限的,所以就有了这个步骤。
单位的打印机型号是惠普的HP DesignJet Z6200 60 英寸照片打印机,最大打印纸张宽度是60英寸,大约就是1524mm左右吧,除了最大尺寸外,日常还用到的纸张宽度有440、610、914、1067、1274等6、7种吧,所以出于节约打印时间和省钱的考虑,为每张图选择最合适的打印纸张宽度也是很有必要的。
判断图像是否需要旋转的思路是这样的:
1、比较图像的宽和高,判断谁是图像的长边和短边。
2、短边如果大于1524mm,这图按1:1就打不出来了,超过打印机最大可装入的纸张的宽度,把这个图像文件放到Oversize_path路径下,后续自己看着办。
3、在短边小于等于1524mm的前提下,根据对图像宽高和长短边的比较,有两种需要旋转的情况:
3.1 如果图像的宽是长边(矮胖的矩形),且宽大于1524mm,那么这图得旋转90°;
3.2 如果图像的高是长边(瘦高的矩形),且高小于1524mm,那么这图也得旋转90°。
*printTOtkinter()是个用tkinter搞的进度显示窗口,就输出下一些文本信息而已。
五、为图像选择最合适的打印纸张尺寸
单位打印纸有438、610、914、1524等7种宽度,现在要选出最适合的一种来进行打印。
在把短边大于1524这种情况排除之后,剩下的图像情况为短边小于1524,即单位的打印机能打印出来了。
这时要判断最佳打印用纸的宽度,有两种情况需要考虑:
1、长边>1524,改用短边来比较选择打印纸宽度。
2、长边 ≤ 1524,用长边来比较选择打印纸宽度。
下面思路就是把要用作比较的边长放入纸张宽度列表,把列表排序后找到比这个边长大一点的那个纸张宽度。
主要的步骤就是这些,再经过一顿复制粘贴完善一下其他细节之后,最后会得到一个存放打印信息的列表,把它用txt存起来,这样后面的PS批量打印需要的信息就全部搞到手了。最后放个gif。
PIL (Python Imaging Library)
Python图像处理库,该库支持多种文件格式,提供强大的图像处理功能。
PIL中最重要的类是Image类,该类在Image模块中定义。
从文件加载图像:
如果成功,这个函数返回一个Image对象。现在你可以使用该对象的属性来探索文件的内容。
format 属性指定了图像文件的格式,如果图像不是从文件中加载的则为 None 。
size 属性是一个2个元素的元组,包含图像宽度和高度(像素)。
mode 属性定义了像素格式,常用的像素格式为:“L” (luminance) - 灰度图, “RGB” , “CMYK”。
如果文件打开失败, 将抛出IOError异常。
一旦你拥有一个Image类的实例,你就可以用该类定义的方法操作图像。比如:显示
( show() 的标准实现不是很有效率,因为它将图像保存到一个临时文件,然后调用外部工具(比如系统的默认图片查看软件)显示图像。该函数将是一个非常方便的调试和测试工具。)
接下来的部分展示了该库提供的不同功能。
PIL支持多种图像格式。从磁盘中读取文件,只需使用 Image 模块中的 open 函数。不需要提供文件的图像格式。PIL库将根据文件内容自动检测。
如果要保存到文件,使用 Image 模块中的 save 函数。当保存文件时,文件名很重要,除非指定格式,否则PIL库将根据文件的扩展名来决定使用哪种格式保存。
** 转换文件到JPEG **
save 函数的第二个参数可以指定使用的文件格式。如果文件名中使用了一个非标准的扩展名,则必须通过第二个参数来指定文件格式。
** 创建JPEG缩略图 **
需要注意的是,PIL只有在需要的时候才加载像素数据。当你打开一个文件时,PIL只是读取文件头获得文件格式、图像模式、图像大小等属性,而像素数据只有在需要的时候才会加载。
这意味着打开一个图像文件是一个非常快的操作,不会受文件大小和压缩算法类型的影响。
** 获得图像信息 **
Image 类提供了某些方法,可以操作图像的子区域。提取图像的某个子区域,使用 crop() 函数。
** 复制图像的子区域 **
定义区域使用一个包含4个元素的元组,(left, upper, right, lower)。坐标原点位于左上角。上面的例子提取的子区域包含300x300个像素。
该区域可以做接下来的处理然后再粘贴回去。
** 处理子区域然后粘贴回去 **
当往回粘贴时,区域的大小必须和参数匹配。另外区域不能超出图像的边界。然而原图像和区域的颜色模式无需匹配。区域会自动转换。
** 滚动图像 **
paste() 函数有个可选参数,接受一个掩码图像。掩码中255表示指定位置为不透明,0表示粘贴的图像完全透明,中间的值表示不同级别的透明度。
PIL允许分别操作多通道图像的每个通道,比如RGB图像。 split() 函数创建一个图像集合,每个图像包含一个通道。 merge() 函数接受一个颜色模式和一个图像元组,然后将它们合并为一个新的图像。接下来的例子交换了一个RGB图像的三个通道。
** 分离和合并图像通道 **
对于单通道图像, split() 函数返回图像本身。如果想处理各个颜色通道,你可能需要先将图像转为RGB模式。
resize() 函数接受一个元组,指定图像的新大小。
rotate() 函数接受一个角度值,逆时针旋转。
** 基本几何变换 **
图像旋转90度也可以使用 transpose() 函数。 transpose() 函数也可以水平或垂直翻转图像。
** transpose **
transpose() 和 rotate() 函数在性能和结果上没有区别。
更通用的图像变换函数为 transform() 。
PIL可以转换图像的像素模式。
** 转换颜色模式 **
PIL库支持从其他模式转为“L”或“RGB”模式,其他模式之间转换,则需要使用一个中间图像,通常是“RGB”图像。
ImageFilter 模块包含多个预定义的图像增强过滤器用于 filter() 函数。
** 应用过滤器 **
point() 函数用于操作图像的像素值。该函数通常需要传入一个函数对象,用于操作图像的每个像素:
** 应用点操作 **
使用以上技术可以快速地对图像像素应用任何简单的表达式。可以结合 point() 函数和 paste 函数修改图像。
** 处理图像的各个通道 **
注意用于创建掩码图像的语法:
Python计算逻辑表达式采用短路方式,即:如果and运算符左侧为false,就不再计算and右侧的表达式,而且返回结果是表达式的结果。比如 a and b 如果a为false则返回a,如果a为true则返回b,详见Python语法。
对于更多高级的图像增强功能,可以使用 ImageEnhance 模块中的类。
可以调整图像对比度、亮度、色彩平衡、锐度等。
** 增强图像 **
PIL库包含对图像序列(动画格式)的基本支持。支持的序列格式包括 FLI/FLC 、 GIF 和一些实验性的格式。 TIFF 文件也可以包含多个帧。
当打开一个序列文件时,PIL库自动加载第一帧。你可以使用 seek() 函数 tell() 函数在不同帧之间移动。
** 读取序列 **
如例子中展示的,当序列到达结尾时,将抛出EOFError异常。
注意当前版本的库中多数底层驱动只允许seek到下一帧。如果想回到前面的帧,只能重新打开图像。
以下迭代器类允许在for语句中循环遍历序列:
** 一个序列迭代器类 **
PIL库包含一些函数用于将图像、文本打印到Postscript打印机。以下是一个简单的例子。
** 打印到Postscript **
如前所述,可以使用 open() 函数打开图像文件,通常传入一个文件名作为参数:
如果打开成功,返回一个Image对象,否则抛出IOError异常。
也可以使用一个file-like object代替文件名(暂可以理解为文件句柄)。该对象必须实现read,seek,tell函数,必须以二进制模式打开。
** 从文件句柄打开图像 **
如果从字符串数据中读取图像,使用StringIO类:
** 从字符串中读取 **
如果图像文件内嵌在一个大文件里,比如 tar 文件中。可以使用ContainerIO或TarIO模块来访问。
** 从tar文档中读取 **
** 该小节不太理解,请参考原文 **
有些解码器允许当读取文件时操作图像。通常用于在创建缩略图时加速解码(当速度比质量重要时)和输出一个灰度图到激光打印机时。
draft() 函数。
** Reading in draft mode **
输出类似以下内容:
注意结果图像可能不会和请求的模式和大小匹配。如果要确保图像不大于指定的大小,请使用 thumbnail 函数。
Python2.7 教程 PIL
http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/00140767171357714f87a053a824ffd811d98a83b58ec13000
Python 之 使用 PIL 库做图像处理
http://www.cnblogs.com/way_testlife/archive/2011/04/17/2019013.html
来自 http://effbot.org/imagingbook/introduction.htm
from PIL import Imageimport os
import cv2
from math import *
import numpy as np
path_old ='G:'
degrees=[]
for k in range(1,25):
degrees.append(k*15)
for item in os.listdir(path_old):
in_imgpath = path_old + item
out_name = os.path.splitext(item)[0]
print(in_imgpath)