Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"SystemError: tile cannot extend outside image" in PIL during save image

I have this Image =>

enter image description here

here is, all coordinates of above yellow boxes that is written in 3.txt file.

#Y   X Height     Width 

46 135 158 118 
46 281 163 104 
67 494 188 83 
70 372 194 101 
94 591 207 98 
252 132 238 123 
267 278 189 105 
320 741 69 141 
322 494 300 135 
323 389 390 124 
380 726 299 157 
392 621 299 108 
449 312 227 93 
481 161 425 150 
678 627 285 91 
884 13 650 437 
978 731 567 158 
983 692 60 43 
1402 13 157 114 

My intension is to crop those boxes and save all boxes as Image. I have written a code for that but getting error.

Here is my code =>

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
from os import listdir
#from scipy.misc import imsave

ARR = np.empty([1,4])
# print(ARR)

i = 0
k = 0
img = Image.open('3.png')

fo = open("3.txt", "r")
for line in fo:
    if not line.startswith('#'):
        for word in line.split():

            ARR[0][i] = int(word)
            print(int(word))
            # ARR[0][i] = int(word)
            i = i +1

    img2 = img.crop((int(ARR[0][1]), int(ARR[0][0]), int(ARR[0][0] + ARR[0][2]), int(ARR[0][1] + ARR[0][3])))
    name = "new-img" + str(k) + ".png"
    img2.save(name)
    k = k + 1
    i = 0

I am getting these error =>

Traceback (most recent call last): File "reshape.py", line 26, in img2.save(name) File "/usr/lib/python2.7/dist-packages/PIL/Image.py", line 1468, in save save_handler(self, fp, filename) File "/usr/lib/python2.7/dist-packages/PIL/PngImagePlugin.py", line 624, in _save ImageFile._save(im, _idat(fp, chunk), [("zip", (0,0)+im.size, 0, rawmode)]) File "/usr/lib/python2.7/dist-packages/PIL/ImageFile.py", line 462, in _save e.setimage(im.im, b) SystemError: tile cannot extend outside image

How do I fix these?

like image 455
Sudip Das Avatar asked Mar 30 '17 15:03

Sudip Das


3 Answers

With reference to the comments, the error occurred due to improper passing of the coordinates to PIL's crop() function.

As mentioned in the documentation, the function returns an image having taken in a tuple of four (x, y, width and height).

In the given text file the y coordinate is mentioned in the first column and x coordinate in the second column. The crop() function however accepts the value of x coordinate as the first parameter and the y coordinate as the second parameter.

The same applies for OpenCV as well

Here is ANOTHER POST regarding the same.

like image 104
Jeru Luke Avatar answered Nov 16 '22 13:11

Jeru Luke


The mentioned way on the internet is like this:

imageScreenshot.crop((x, y, width, height))

But the correct way is this:

imageScreenshot.crop((x, y, x + width, y + height))

Meaning that you should add the x to the width and y to the height.
This is a simple example (driver is for python selenium):

def screenShotPart(x, y, width, height) -> str:
    screenshotBytes = driver.get_screenshot_as_png()
    imageScreenshot = Image.open(BytesIO(screenshotBytes))
    imageScreenshot = imageScreenshot.crop((x, y, x + width, y + height))
    imagePath = pathPrefix + "_____temp_" + str(time.time()).replace(".", "") + ".png"
    imageScreenshot.save(imagePath)

Hope it helps.

like image 36
AmirHossein Avatar answered Nov 16 '22 13:11

AmirHossein


In my case the issue was that I was specifying start and end coordinates where the start X and start Y were not always less than the end X and Y. You cannot do this.

For example,

Start: (0, 50) End: (50, 0)

These coordinates make sense to me, but should actually be specified as:

Start: (0, 0) End: (50, 50)

Visually the same rectangle, but the latter is required for Pillow to crop.

like image 4
user123959 Avatar answered Nov 16 '22 15:11

user123959