PIL裁剪与粘贴问题:裁剪不产生裁剪图像

2 投票
2 回答
5067 浏览
提问于 2025-04-16 04:50

我想把一张图片裁剪掉一部分,然后把裁剪好的图片粘贴到另一张图片的中间。理想情况下,我希望裁剪后的图片比被粘贴的那张图片要小,这样在粘贴的图片周围就会有一个边框,但我不知道这样做是否可行。

这是我尝试过的代码(还有出现的错误信息):

>>> import Image
>>> grey = Image.new('RGB', (200, 200), "grey")
>>> House = Image.open("House01.jpg")
>>> print grey.size, grey.mode, grey.format
>>>(200, 200) RGB None
>>> print House.size, House.mode, House.format
>>>(300, 300) RGB JPEG
>>> box = (25, 25, 25, 25)
>>> House.crop(box)
>>>Image._ImageCrop image mode=RGB size=0x0 at 0x11AD210>
>>> region = House.crop(box)
>>> region.show()
>>>Traceback (most recent call last):
 >>> File "<pyshell#28>", line 1, in <module>
    region.show()
>>>  File "C:\Python26\lib\site-packages\PIL\Image.py", line 1483, in show
    _show(self, title=title, command=command)
>>>  File "C:\Python26\lib\site-packages\PIL\Image.py", line 2123, in _show
    apply(_showxv, (image,), options)
>>>  File "C:\Python26\lib\site-packages\PIL\Image.py", line 2127, in _showxv
    apply(ImageShow.show, (image, title), options)
>>>  File "C:\Python26\lib\site-packages\PIL\ImageShow.py", line 41, in show
    if viewer.show(image, title=title, **options):
>>>  File "C:\Python26\lib\site-packages\PIL\ImageShow.py", line 66, in show
    self.show_image(image, **options)
>>>  File "C:\Python26\lib\site-packages\PIL\ImageShow.py", line 85, in show_image
    return self.show_file(self.save_image(image), **options)
>>>  File "C:\Python26\lib\site-packages\PIL\ImageShow.py", line 81, in save_image
    return image._dump(format=self.get_format(image))
>>>  File "C:\Python26\lib\site-packages\PIL\Image.py", line 493, in _dump
    self.save(file, format)
>>>  File "C:\Python26\lib\site-packages\PIL\Image.py", line 1439, in save
    save_handler(self, fp, filename)
>>>  File "C:\Python26\lib\site-packages\PIL\BmpImagePlugin.py", line 242, in _save
    ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, stride, -1))])
>>>  File "C:\Python26\lib\site-packages\PIL\ImageFile.py", line 498, in _save
    e.setimage(im.im, b)
>>>SystemError: tile cannot extend outside image

我注意到'区域'的大小变成了(0,0),但我不明白为什么会这样。

如果能帮我解决这个问题,那就太好了,谢谢!

2 个回答

0

我之前也遇到过类似的错误,怎么也解决不了。后来我意识到,问题出在传给Image.crop()的参数上。你可以看到你的图片大小是(0,0),所以根本没有内容可显示。你设置的裁剪范围是从(25,25)到(25,25),这就相当于没有裁剪区域。

如果你想要裁剪出一个25x25的图片(从左上角开始):

>> import Image
>>> grey = Image.new('RGB', (200, 200), "grey")
>>> House = Image.open("House01.jpg")
>>> print grey.size, grey.mode, grey.format
>>>(200, 200) RGB None
>>> print House.size, House.mode, House.format
>>>(300, 300) RGB JPEG
>>> box = (0, 0, 25, 25)
>>> House.crop(box)
>>>Image._ImageCrop image mode=RGB size=0x0 at 0x11AD210>
>>> region = House.crop(box)
>>> region.show()

如果你想从中心或者其他点开始裁剪,可以参考这个链接

7

PIL文档中关于裁剪方法的说明是:

这个方法会从当前的图片中返回一个矩形区域。这个区域用一个包含四个数字的元组来定义,分别表示左边、上边、右边和下边的像素坐标。

这个操作是懒惰的。也就是说,对源图片的修改可能会或可能不会在裁剪后的图片中反映出来。如果你想要一个独立的副本,可以在裁剪后的副本上调用加载方法。

所以,你应该尝试 region = House.crop(box).load() 来确保你得到的是一个真正的裁剪副本。

更新:
实际上,似乎上面的做法只有在使用PIL 1.1.6及以后的版本时才有效。在此之前的版本中,我猜 load() 不会返回任何东西,所以你不能把这些操作连在一起。在这种情况下,可以使用:

region = House.crop(box)
region.load()

撰写回答