1

I have a python code that loops through an image and copies them to an array in RGBA format, however the code is incredibly slow, 10 images each 256x256 took more than 5 minutes to process, any ideas how this code can be improved?

self.pixelsArray = array('B')

def extractPixelsFromImage(self):
    pixels = self.image.pixels 
    for y in range(self.height):
        for x in range(self.width):

            i = (x + (self.height-1-y)*self.width) * 4

            r = int (max (0, min (255, 255 * pixels [i    ])))
            g = int (max (0, min (255, 255 * pixels [i + 1])))
            b = int (max (0, min (255, 255 * pixels [i + 2])))
            a = int (max (0, min (255, 255 * pixels [i + 3])))

            self.pixelsArray.append(r)
            self.pixelsArray.append(g)
            self.pixelsArray.append(b)
            self.pixelsArray.append(a)
philshem
  • 24,761
  • 8
  • 61
  • 127
Anton Banchev
  • 541
  • 8
  • 28

2 Answers2

3

One little improvement that you can make is instead of append four times for r, g, b and a to the array, create a list and use the extend method, like this:

self.pixels_array = array('B')

def extract_pixels_from_image(self):
    pixels = self.image.pixels 
    for y in range(self.height):
        for x in range(self.width):

            i = (x + (self.height - 1 - y) * self.width) * 4

            r = int(max(0, min(255, 255 * pixels[i])))
            g = int(max(0, min(255, 255 * pixels[i + 1])))
            b = int(max(0, min(255, 255 * pixels[i + 2])))
            a = int(max(0, min(255, 255 * pixels[i + 3])))

            self.pixels_array.extend([r, g, b, a])

Sorry for change your naming style, just don't use camel case style in variables and method names is not pythonic.

Ricardo Murillo
  • 2,775
  • 1
  • 18
  • 12
  • 1
    I will check the "extend" speed, I was thinking that maybe each append is creating a new array, if this is the case it may be 4 times faster. – Anton Banchev May 29 '14 at 10:47
  • 1
    Well, after taking a deeper look at the code(this code and the other parts) it seems like this is not the issue that makes it run so slow, so I am accepting this answer as correct as I don't think there can be a better way to optimize it in a meaningful way. – Anton Banchev May 30 '14 at 07:12
0

The first thing I would try would be to replace range with xrange, as long as you don't need the whole array in memory.

  • range creates a list, so if you do range(1, 10000000) it creates a list in memory with 10000000 elements.

  • xrange is a sequence object that evaluates lazily.

(source)

Community
  • 1
  • 1
philshem
  • 24,761
  • 8
  • 61
  • 127