Как разбить изображение на несколько частей в Python

Я пытаюсь разделить фотографию на несколько частей с помощью PIL.

def crop(Path,input,height,width,i,k,x,y,page):
    im = Image.open(input)
    imgwidth = im.size[0]
    imgheight = im.size[1]
    for i in range(0,imgheight-height/2,height-2):
        print i
        for j in range(0,imgwidth-width/2,width-2):
            print j
            box = (j, i, j+width, i+height)
            a = im.crop(box)
            a.save(os.path.join(Path,"PNG","%s" % page,"IMG-%s.png" % k))
            k +=1

но, похоже, это не работает. Он разбивает фотографию, но не точно (вы можете попробовать).

6 ответов


from PIL import Image

def crop(path, input, height, width, k, page, area):
    im = Image.open(input)
    imgwidth, imgheight = im.size
    for i in range(0,imgheight,height):
        for j in range(0,imgwidth,width):
            box = (j, i, j+width, i+height)
            a = im.crop(box)
            try:
                o = a.crop(area)
                o.save(os.path.join(path,"PNG","%s" % page,"IMG-%s.png" % k))
            except:
                pass
            k +=1

проще, чем все это, использовать колесо, которое кто-то другой изобрел :) это может быть более сложным для настройки, но тогда это легко использовать.

эти инструкции предназначены для Windows 7; они могут потребоваться для других ОС.

получить и установить pip из здесь.

загрузите установочный архив и извлеките его в корневой каталог установки Python. Откройте консоль и введите (если я правильно помню):

python get-pip.py install

тогда вам и установите модуль image_slicer через pip, введя в консоли следующую команду:

python -m pip install image_slicer

скопируйте изображение, которое вы хотите нарезать в корневой каталог Python, откройте оболочку python (а не" командную строку") и введите следующие команды:

import image_slicer
image_slicer.slice('huge_test_image.png', 14)

красота этого модуля в том, что он

  1. устанавливается в python
  2. можно вызвать разделение изображения с двумя строками кода
  3. можно в любое четное число в виде изображения параметр среза (например, 14 в этом примере)
  4. принимает этот параметр и автоматически разбивает данное изображение на множество срезов и автоматически сохраняет результирующие пронумерованные плитки в том же каталоге и, наконец,
  5. имеет функцию сшивания плиток изображений (которые я еще не тестировал); файлы, по-видимому, должны быть названы в честь соглашения, которое вы увидите в файлах разделения после тестирования image_slicer.функция среза.

  1. crop было бы более многоразовым функция если вы отделяете обрезка кода из сохранение изображений код. Он также сделает звонок подпись проще.
  2. im.crop возвращает a Image._ImageCrop экземпляра. Такие экземпляры не имеют метода Save. Вместо этого необходимо вставить Image._ImageCrop экземпляр на a новый Image.Image
  3. ваши диапазоны не имеют право размер шага. (Почему height-2 и не height? например. Зачем останавливаться? на imgheight-(height/2)?).

Итак, вы можете попробовать вместо этого что-то вроде этого:

import Image
import os

def crop(infile,height,width):
    im = Image.open(infile)
    imgwidth, imgheight = im.size
    for i in range(imgheight//height):
        for j in range(imgwidth//width):
            box = (j*width, i*height, (j+1)*width, (i+1)*height)
            yield im.crop(box)

if __name__=='__main__':
    infile=...
    height=...
    width=...
    start_num=...
    for k,piece in enumerate(crop(infile,height,width),start_num):
        img=Image.new('RGB', (height,width), 255)
        img.paste(piece)
        path=os.path.join('/tmp',"IMG-%s.png" % k)
        img.save(path)

разделение изображения на плитки пикселей MxN (при условии, что im numpy.ndarray):

tiles = [im[x:x+M,y:y+N] for x in range(0,im.shape[0],M) for y in range(0,im.shape[1],N)]

в случае, если вы хотите разделить изображение на четыре части:

M = im.shape[0]//2
N = im.shape[1]//2

плитка[0] держит верхнюю левую плитку


Это мои инструменты скрипта, это очень образец для разбиения css-sprit изображения на значки:

Usage: split_icons.py img dst_path width height
Example: python split_icons.py icon-48.png gtliu 48 48

Сохранить код в split_icons.py :

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
import sys
import glob
from PIL import Image

def Usage():
    print '%s img dst_path width height' % (sys.argv[0])
    sys.exit(1)

if len(sys.argv) != 5:
    Usage()

src_img = sys.argv[1]
dst_path = sys.argv[2]

if not os.path.exists(sys.argv[2]) or not os.path.isfile(sys.argv[1]):
    print 'Not exists', sys.argv[2], sys.argv[1]
    sys.exit(1)

w, h = int(sys.argv[3]), int(sys.argv[4])
im = Image.open(src_img)
im_w, im_h = im.size
print 'Image width:%d height:%d  will split into (%d %d) ' % (im_w, im_h, w, h)
w_num, h_num = int(im_w/w), int(im_h/h)

for wi in range(0, w_num):
    for hi in range(0, h_num):
        box = (wi*w, hi*h, (wi+1)*w, (hi+1)*h)
        piece = im.crop(box)
        tmp_img = Image.new('L', (w, h), 255)
        tmp_img.paste(piece)
        img_path = os.path.join(dst_path, "%d_%d.png" % (wi, hi))
        tmp_img.save(img_path)

Мне проще skimage.util.view_as_windows или `skimage.утиль.view_as_blocks, который также позволяет настроить шаг

http://scikit-image.org/docs/dev/api/skimage.util.html?highlight=view_as_windows#skimage.util.view_as_windows