2011-05-10 229 views
4

我試圖用PIL將照片拆分爲多個部分。如何在Python中將圖像拆分爲多個部分

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 

但它似乎並沒有工作。它拆分照片,但不是以一種確切的方式(你可以嘗試)。如果從 圖像保存 代碼中分離出來的 裁剪代碼

+0

什麼你的意思是「確切」的寬度和高度? – kindall 2011-05-10 16:47:49

+0

您可以使用列表解析,請參閱我的回答下面的 – Nir 2018-02-10 20:02:31

回答

13
from PIL import Image 
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 
+0

給出一個完整的工作示例.. – 2018-02-07 07:09:51

5
  1. crop將是一個更可重複使用的 功能。這也會使呼叫 簽名更簡單。
  2. im.crop返回一個 Image._ImageCrop實例。這樣的 實例沒有保存方法。 相反,你必須在 Image._ImageCrop實例粘貼到一個新的 Image.Image
  3. 你的範圍內沒有合適的 步長。 (爲什麼在height-2而不是 height

所以,你可以嘗試,而不是像這樣:

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) 
+0

感謝您的解決方案,但它不適用於我,圖片沒有裁剪好,我看到紅色,我想這個問題也許在這裏:'img.paste piece)' – ElTero 2011-05-10 21:07:41

+0

如果你有內存限制,這是一個特別好的解決方案。使用image_slicer時,大圖像可能會在內存不足的機器上失敗。 – 2017-01-12 13:54:01

12

簡單得多所有這些是使用車輪別人發明了:)這可能是更多地參與建立,但那麼這是一個簡單的使用。

這些說明適用於Windows 7;他們可能需要適應其他操作系統。

here獲取並安裝點。

下載安裝檔案,並將其解壓到您的根目錄Python安裝目錄。通過PIP

python get-pip.py install 

然後獲取並安裝image_slicer模塊,通過在控制檯輸入以下命令:打開一個控制檯和類型(如果我沒有記錯)

python -m pip install image_slicer 

複製想要的圖像切片到Python根目錄下,打開一個蟒殼(不是「命令行」),並輸入以下命令:

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

該模塊的優點在於它

  1. 安裝在蟒
  2. 可以調用用的兩行代碼的圖像分割
  3. 接受任何偶數作爲圖像切片參數(例如在這個例子中)
  4. 注意到該參數並自動給定的圖像分成很多片段,並在同一目錄下自動保存生成的編號的塊,最後
  5. 具有這樣的功能拼接圖像塊重新走到一起14 (我還沒有測試過);文件顯然必須按照慣例命名,您將在測試image_slicer.slice函數後在分割文件中看到該約定。您希望將圖像分解到四個

    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)] 
    

    在這種情況下:

+1

它看起來不錯,但其文檔很差。一旦它們被創建,它也可以很好地控制瓷磚,但不容易看出圖像將如何切割。我期待有一種元組來設置行數和列數 – 2017-06-08 14:01:35

2

分割圖像M×N個像素的磚(假設IM是numpy.ndarray)

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

磚[0]保留左上方的圖塊

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)