Как разделить изображение на несколько частей в Python - PullRequest
11 голосов
/ 10 мая 2011

Я пытаюсь разделить фотографию на несколько частей, используя 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

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

Ответы [ 7 ]

24 голосов
/ 13 августа 2011
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
20 голосов
/ 26 ноября 2014

Редактировать: я полагаю, что в этом ответе не было цели разрезать изображение на прямоугольники в столбцах и строках.Этот ответ разрезается только на строки.Похоже, другие ответы вырезаны в столбцах и строках.

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

Эти инструкции предназначены для 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.slice.
11 голосов
/ 30 ноября 2017

Разделение изображения на плитки пикселей MxN (при условии, что im is 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] содержит верхнюю левую плитку

10 голосов
/ 10 мая 2011
  1. crop будет более многоразовым функция, если вы отделяете код обрезки из сохранение изображения код. Это также сделало бы звонок подпись проще.
  2. im.crop возвращает Image._ImageCrop экземпляр. такие экземпляры не имеют метода сохранения. Вместо этого вы должны вставить Image._ImageCrop экземпляр на новый 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)
1 голос
/ 20 февраля 2019

Вот краткое, чисто Python-решение, которое работает как в Python 3, так и в 2:

from PIL import Image

infile = '20190206-135938.1273.Easy8thRunnersHopefully.jpg'
chopsize = 300

img = Image.open(infile)
width, height = img.size

# Save Chops of original image
for x0 in range(0, width, chopsize):
   for y0 in range(0, height, chopsize):
      box = (x0, y0,
             x0+chopsize if x0+chopsize <  width else  width - 1,
             y0+chopsize if y0+chopsize < height else height - 1)
      print('%s %s' % (infile, box))
      img.crop(box).save('zchop.%s.x%03d.y%03d.jpg' % (infile.replace('.jpg',''), x0, y0))

Примечания:

Коррекция, проходящая справа и снизу исходного изображения, корректируетсяк исходному пределу изображения и содержат только оригинальные пиксели. Легко выбрать другой размер chopsize для w и h, используя две переменные chopsize и заменяя chopsize соответствующим образом в приведенном выше коде.
0 голосов
/ 04 марта 2018

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

http://scikit -image.org / docs / dev / api / skimage.util.html? выделить = view_as_windows # skimage.util.view_as_windows

0 голосов
/ 11 января 2018

Это мои инструменты-скрипты, это очень простой пример разделения изображения 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)
...