可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm trying to split a photo into multiple pieces using 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
but it doesn't seem to be working. It splits the photo but not in an exact way (you can try it).
回答1:
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
回答2:
Simpler than all these is to use a wheel someone else invented :) It may be more involved to set up, but then it's a snap to use.
These instructions are for Windows 7; they may need to be adapted for other OSs.
Get and install pip from here.
Download the install archive, and extract it to your root Python installation directory. Open a console and type (if I recall correctly):
python get-pip.py install
Then get and install the image_slicer module via pip, by entering the following command at the console:
python -m pip install image_slicer
Copy the image you want to slice into the Python root directory, open a python shell (not the "command line"), and enter these commands:
import image_slicer
image_slicer.slice('huge_test_image.png', 14)
The beauty of this module is that it
- Is installed in python
- Can invoke an image split with two lines of code
- Accepts any even number as an image slice parameter (e.g. 14 in this example)
- Takes that parameter and automagically splits the given image into so many slices, and auto-saves the resultant numbered tiles in the same directory, and finally
- Has a function to stitch the image tiles back together (which I haven't yet tested); files apparently must be named after the convention which you will see in the split files after testing the image_slicer.slice function.
回答3:
crop
would be a more reusable
function if you separate the
cropping code from the
image saving
code. It would also make the call
signature simpler.
im.crop
returns a
Image._ImageCrop
instance. Such
instances do not have a save method.
Instead, you must paste the
Image._ImageCrop
instance onto a
new Image.Image
- Your ranges do not have the right
step sizes. (Why
height-2
and not
height
? for example. Why stop at
imgheight-(height/2)
?).
So, you might try instead something like this:
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)
回答4:
Splitting image to tiles of MxN pixels (assuming 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)]
In the case you want to split the image to four pieces:
M = im.shape[0]//2
N = im.shape[1]//2
tiles[0] holds the upper left tile
回答5:
This is my script tools, it is very sample to splite css-sprit image into icons:
Usage: split_icons.py img dst_path width height
Example: python split_icons.py icon-48.png gtliu 48 48
Save code into 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)
回答6:
I find it easier to skimage.util.view_as_windows
or `skimage.util.view_as_blocks which also allows you to configure the step
http://scikit-image.org/docs/dev/api/skimage.util.html?highlight=view_as_windows#skimage.util.view_as_windows