Python Imaging Library (PIL) http://www.pythonware.com/products/pil/ Возможности PIL: Групповая обработка изображений PIL идеально подходит для работы с группами изображений. С помощью PIL можно создавать превью, преобразовать изображения из одного формата в другой, распечатывать изображения и т.д. Отображение изображений Для отладки удобнее всего использовать метод im.show(). Открывает изображение в стандартном браузере. PIL также может создавать объекты, с которыми работают различные модули для создания GUI, такие как PythonWin, Tkinter, PyQT4 Возможности обработки изображений Операции на пикселями, фильтры, преобразование цветового пространства Изменение размера изображения, поворот, аффинные преобразования Метод histogram, который может служить для автоматического улучшения контраста и извлечения статистических данных из изображения Основные понятия Размер (атрибут size) Это кортеж, состоящий соответственно из высоты и ширины в пикселях Система координат В Питоне используется Картезианская система координат с началом отсчета в левом верхнем углу. Например, координаты прямоугольника 800х600 передаются как (0,0,800,600) Основные понятия Расширение файла (атрибут format) Функция open узнает расширение из содержания файла, функция save использует название, чтобы определить формат (если он не указан конкретно) Каналы (метод getbands) Каждое изображение может состоять из одного или более каналов. Цветовая модель (атрибут mode) Определяет глубину и цвет пикселя Основные понятия Основные цветовые модели: 1 (1-bit, ч/б) L (8-bit pixels, ч/б) P (8-bit pixels, пользовательская палитра) RGB (3x8-bit pixels, естественный цвет – true color) RGBA (4x8-bit pixels, естественный цвет с маской прозрачности) CMYK (4x8-bit pixels, цветоделение) YCbCr (3x8-bit pixels, цветной видеоформат) Основные понятия Палитра Цветовая модель палитра (“P”) использует цветовую палитру для определения фактического цвета каждого пикселя Информация (атрибут info) Изображению можно прикрепить дополнительную информацию. info - атрибут типа dictionary Фильтры (NEAREST,BILINEAR,BICUBIC,ANTIALIAS) Используются для операций, которые могут сопоставлять нескольким пикселям один. Фильтры NEAREST – выбирает ближайший пиксель из входного изображения и игнорирует все остальные (обычно идет по умолчанию во всех методах) BILINEAR – использует линейную интерполяцию на области 2x2 BICUBIC – использует линейную интерполяцию на обл. 4x4 ANTIALIAS – вычисляет значение выходного пикселя с помощью высококачественного фильтра субдескретизации на всех пикселях, которые могут влиять на выходное значение. В текущей версии можно использовать только с методами resize и thumbnail Чтение Image.open(infile, mode) im = Image.open(…) создает объект типа Image Это ленивая операция, изначально считывается только информация, необходимая для декодирования изображения (цветовая модель, размер и т.д.) mode – необязательный аргумент, если используется, должен быть “r” infile может быть строкой с путем файла или объектом типа файл(поддерживающим методы read, seek, tell), открытым в бинарном режиме Чтение(Примеры) Обычный случай 1. Чтение из открытого файла 1. 2. fp = open("lena.ppm", "rb") im = Image.open(fp) #бинарный режим Чтение из строки 1. 2. im = Image.open("lena.ppm") import StringIO im = Image.open(StringIO.StringIO(buffer)) Чтение из Tar-архива 1. 2. 3. import TarIO fp = TarIO.TarIO("Imaging.tar", "Imaging/test/lena.ppm") im = Image.open(fp) Сохранение im.save(outfile, format, options) outfile – строка или файловый объект format – формат файла, можно указывать в названии options – дополнительные параметры Определяет формат по названию или указанному формату Пример Пример 1. 2. 3. 4. 5. 6. 7. 8. from PIL import Image ein = Image.open("IMG_3090.jpg") #создаем объект класса Image print ein.size, ein.mode, ein.format # (512, 768) JPEG RGB ein 1= ein.rotate(270, Image.BICUBIC, 1) ein0 = ein.rotate(270, Image.BICUBIC) ein0.save ("einstein0.JPEG") ein1.save("einstein1.JPG") Разница в наличии и отсутствии последнего аргумента ein.rotate(270,Image.BICUBIC, 1) ein.rotate(270,Image.BICUBIC) Пример работы с каналами Пример работы с каналами 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. import Image im = Image.open('C:/panda.jpg') r,g,b = im.split() images = [Image.merge(im.mode, (r,b,g)),Image.merge(im.mode, (b,g,r)),Image.merge(im.mode, (g,b,r))] def create_new(ls, ind): w, h = images[0].size n_ind = ind bgr = Image.new("RGB",(w*(len(ls)) + n_ind*(len(ls)+1),h + n_ind*2),"white") for i in images: assert w, h == i.size bgr.paste(i,(n_ind,ind)) n_ind += ind + w return bgr new_im = create_new(images,30) new_im.show() Пример работы с каналами Конвертация изображений в формат JPEG 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. import os,sys import Image for infile in sys.argv[1:]: f, e = os.path.splitext(infile) # f – имя, e – расширение файла outfile = f + ".jpg" if infile != outfile: # если формат изображения JPEG, то пропускаем его try: Image.open(infile).save(outfile) except IOError: print "cannot convert ", infile Создание превью формата JPEG 2. import os, sys import Image 3. size = 130, 130 4. for infile in sys.argv[1:]: outfile = os.path.splitext(infile)[0] + ".thumbnail" if infile != outfile: try: im = Image.open(infile) im.thumbnail(size,Image.ANTIALIAS) im.save(outfile + ".jpg") except IOError: print "cannot create thumbnail for", infile 1. 5. 6. 7. 8. 9. 10. 11. 12. Обрезка, вставка import Image im = Image.open("C:/munch.jpg") w, h = im.size box = (300, 400, 700, h) region = im.crop(box) region = region.transpose(Image.ROTATE_180) im.paste(region, box) Обрезка, вставка До После Работа с пикселями 1. 2. 3. import Image im = Image.open("flower.jpg") out = im.point(lambda i: i * 3) # увеличилась яркость Обработка изображений Обработка изображений (модуль Image) 1. 2. 3. 4. 5. import Image im = Image.open('car.jpg') im.convert("L").show() # Используется матрица по умолчанию: # L = R * 299/1000 + G * 587/1000 + B * 114/1000 можно использовать im.convert(mode, matrix) с собственной матрицей преобразования matrix Обработка изображений (ImageEnhance) 4. 5. 6. import ImageEnhance enhancer = ImageEnhance.Contrast(im) enhancer.enhance(1.3).show() Обработка изображений (ImageOps) 7. 8. import ImageOps ImageOps.colorize(im, (44,36,12), (242,232,201)).show() Обработка изображений (ImageChops) 10. 11. 12. import ImageChops p = Image.open('paper.jpg‘) ImageChops.multiply(p, i m).show() Обработка изображений Статистика изображения (модуль ImageStat) Позволяет узнать некоторые статистические данные изображения, такие как экстремальные значения пикселей, количество пикселей, среднее значение и т.д. Min и max изображения 1. import Image, ImageStat 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. def minmax(im): stat = ImageStat.Stat(im) # Объект типа Stat min, max = [], [] for band in stat.extrema: #[(min1,max1),…,(minN,maxN)] min.append(band[0]) max.append(band[1]) if len(stat.extrema) == 1: return min[0], max[0] else: return tuple(min), tuple(max) 13. 14. 15. 16. Image = Image.open(" lena.jpg“) print minmax(image) # (52, 10, 0) (255, 237, 231) print minmax(image.convert("L")) # 24 241 Создание CAPTCHA с помощью PIL 1. 2. import Image,ImageDraw,ImageFont import random 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. def create_captcha(charNum, fontSize): #задаем список букв, из которых будем далее выбирать: alphArr = ['A','B','C','D','E','F','G','H', 'J','K','L','M','N','O','P','R','S','T', 'W','X','Z','0','1','2','3','4','5','6','8'] font = ImageFont.truetype('ARIAL.TTF',fontSize) # создаем объект Font width, height = font.getsize("W") #ширина и высота текста interval = width width, height = (width + 5)*charNum, height + 20 #размеры фона image = Image.new("RGB",(width,height), (192,192,192)) #создаем фон draw = ImageDraw.Draw(image) #создаем из фона объект Draw, чтобы можно было рисовать на нем Создание CAPTCHA с помощью PIL 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. for i in range(0, charNum): #создаем фон для буквы: charImg = Image.new("RGB",(fontSize + 10, fontSize + 10),"black") tmpDraw = ImageDraw.Draw(charImg) #помещаем на фон случайную букву случайного цвета: tmpDraw.text( (3, 1), random.choice(alphArr), font = font, fill = (random.randint(20,150), random.randint(20, 140), random.randint(160, 200)) ) charImg = charImg.rotate(random.randint(-30, 30)) #создаем маску, чтобы фон буквы стал прозрачным: mask = Image.new('L',(fontSize + 10, fontSize + 10),0) mask.paste(charImg,(0,0)) hpos = 10 + (i*interval + random.randint(10, interval - 10)) vpos = random.randint(10, 20) image.paste(charImg,(hpos,vpos),mask) #два раза для лучшей видимости image.paste(charImg,(hpos,vpos),mask) Создание CAPTCHA с помощью PIL 1. 2. 3. for i in range(0,random.randint(3,5)): draw.line( (random.randint(6,width - 6), random.randint(3,height-3), 4. random.randint(6, width - 6), random.randint(2, height - 3)), 5. fill = (random.randint(70,150), random.randint(20,220), random.randint(160,220)), 6. 7. 8. 9. width = random.randint(1,2)) image.save(“captcha.jpg”) create_captcha(7, 40) Список Литературы http://www.pythonware.com/library/pil/handbook/index. htm http://blog.objectgraph.com/index.php/2007/01/19/pilon-captcha-transparency-and-masking-for-captcha/