def from_surface(surface, threshold=127): """ **pyjsdl.mask.from_surface** Return Mask derived from surface using alpha transparency. Optional argument to set alpha threshold. """ mask = Mask((surface.width, surface.height)) if not mask.bit: return None imagedata = surface.getImageData(0, 0, surface.width, surface.height) data = imagedata.data width, height = surface.width * 4, surface.height for y in range(0, height): xpix = 0 i = (y * width) + 3 bitset = mask.bit[y] bit = bitset._bit _data = bitset._data._data for x in range(0, width, 4): if data[i + x] > threshold: index = ~(~(xpix / bit)) _data[index] = _data[index] | bitset._bitmask[xpix % bit] xpix += 1 return mask
def blit_array(surface, array): """ Generates image pixels from array data. Arguments include destination Surface and array containing image data. """ try: imagedata = array.getImageData() except TypeError: imagedata = surface.getImageData(0, 0, surface.width, surface.height) if len(array._shape) == 2: array2d = ImageMatrix(imagedata) for y in range(array2d.getHeight()): for x in range(array2d.getWidth()): # __pragma__ ('opov') value = array[x,y] array2d[y,x] = (value>>16 & 0xff, value>>8 & 0xff, value & 0xff, 255) # __pragma__ ('noopov') imagedata = array2d.getImageData() else: imagedata.data.set(array.getArray()) surface.putImageData(imagedata, 0, 0, 0, 0, surface.width, surface.height) return None
def from_threshold(surface, color, threshold=(0, 0, 0, 255)): """ **pyjsdl.mask.from_threshold** Return Mask from surface using a given color. Optional threshold argument to set color range and alpha threshold. """ mask = Mask((surface.width, surface.height)) if not mask.bit: return None imagedata = surface.getImageData(0, 0, surface.width, surface.height) data = imagedata.data if threshold == (0, 0, 0, 255): color = Color(color) width, height = surface.width * 4, surface.height for y in range(0, height): xpix = 0 i = y * width bitset = mask.bit[y] bit = bitset._bit _data = bitset._data._data for x in range(0, width, 4): ix = i + x if (data[ix] == color.r and data[ix + 1] == color.g and data[ix + 2] == color.b and data[ix + 3] >= threshold[3]): index = ~(~(xpix / bit)) _data[index] = _data[index] | bitset._bitmask[xpix % bit] xpix += 1 else: color = Color(color) col = {} col['r1'] = color.r - threshold[0] - 1 col['r2'] = color.r + threshold[0] + 1 col['g1'] = color.g - threshold[1] - 1 col['g2'] = color.g + threshold[1] + 1 col['b1'] = color.b - threshold[2] - 1 col['b2'] = color.b + threshold[2] + 1 col['a'] = threshold[3] - 1 width, height = surface.width * 4, surface.height for y in range(0, height): xpix = 0 i = y * width bitset = mask.bit[y] bit = bitset._bit _data = bitset._data._data for x in range(0, width, 4): ix = i + x if ((col['r1'] < data[ix] < col['r2']) and (col['g1'] < data[ix + 1] < col['g2']) and (col['b1'] < data[ix + 2] < col['b2']) and (data[ix + 3] > col['a'])): index = ~(~(xpix / bit)) _data[index] = _data[index] | bitset._bitmask[xpix % bit] xpix += 1 return mask
def getImageData(self): """ Get ImageData. """ index = 0 for x in range(self._imagedata.height): for y in range(self._imagedata.width): self._imagedata.data[index + 3] = self[y, x] index += 4 return self._imagedata.getImageData()
def getImageData(self): """ Get ImageData. """ index = 0 for x in range(self._imagedata.height): for y in range(self._imagedata.width): # __pragma__ ('opov') self._imagedata.data[index + 3] = self[y, x] # __pragma__ ('noopov') index += 4 return self._imagedata.getImageData()
def __init__(self, imagedata): self._imagedata = ImageData(imagedata) array = Ndarray(self._imagedata.data) array.setshape(self._imagedata.height, self._imagedata.width, 4) data = Uint32Array(self._imagedata.height * self._imagedata.width) index = 0 for x in range(self._imagedata.width): for y in range(self._imagedata.height): data[index] = (array[y, x, 0] << 16 | array[y, x, 1] << 8 | array[y, x, 2] | array[y, x, 3] << 24) index += 1 Ndarray.__init__(self, data, 'uint32') self.setshape(self._imagedata.width, self._imagedata.height)
def from_threshold(surface, color, threshold=(0,0,0,255)): """ **pyjsdl.mask.from_threshold** Return Mask from surface using a given color. Optional threshold argument to set color range and alpha threshold. """ mask = Mask((surface.width, surface.height)) if not mask.bit: return None pixels = surface.impl.getImageData(0, 0, surface.width, surface.height) if threshold == (0,0,0,255): color = Color(color) color = (color.r,color.g,color.b) width, height = surface.width*4, surface.height for y in range(0, height): xpix = 0 i = y*width for x in range(0, width, 4): ix = i+x if (surface._getPixel(pixels, ix) == color[0] and surface._getPixel(pixels, ix+1) == color[1] and surface._getPixel(pixels, ix+2) == color[2] and surface._getPixel(pixels, ix+3) >= threshold[3]): mask.set_at((xpix,y)) xpix += 1 else: color = Color(color) col = {} for i, c in enumerate(('r','g','b')): if threshold[i]: col[c+'1'] = color[i] - threshold[i] - 1 col[c+'2'] = color[i] + threshold[i] + 1 else: col[c+'1'] = color[i] - 1 col[c+'2'] = color[i] + 1 col['a'] = threshold[3] - 1 width, height = surface.width*4, surface.height for y in range(0, height): xpix = 0 i = y*width for x in range(0, width, 4): ix = i+x if ((col['r1'] < surface._getPixel(pixels, ix) < col['r2']) and (col['g1'] < surface._getPixel(pixels, ix+1) < col['g2']) and (col['b1'] < surface._getPixel(pixels, ix+2) < col['b2']) and (surface._getPixel(pixels, ix+3) > col['a'])): mask.set_at((xpix,y)) xpix += 1 return mask
def getImageData(self): """ Get ImageData. """ index = 0 for x in range(self._imagedata.height): for y in range(self._imagedata.width): dat = self[y, x] self._imagedata.data[index] = dat >> 16 & 0xff self._imagedata.data[index + 1] = dat >> 8 & 0xff self._imagedata.data[index + 2] = dat & 0xff self._imagedata.data[index + 3] = dat >> 24 & 0xff index += 4 return self._imagedata.getImageData()
def _overlap(mask1, mask2, offset): if offset[0] > 0: x1 = offset[0] x2 = 0 else: x1 = 0 x2 = -offset[0] if offset[1] > 0: y1 = offset[1] y2 = 0 else: y1 = 0 y2 = -offset[1] w = min(mask1.width - x1, mask2.width - x2) h = min(mask1.height - y1, mask2.height - y2) if w > 0 and h > 0: for y in range(h): bitset1 = mask1.bit[y1 + y] bitset2 = mask2.bit[y2 + y] _bitset1 = _bitset_get(bitset1, x1, x1 + w) _bitset2 = _bitset_get(bitset2, x2, x2 + w) intersect = _intersects(_bitset1, _bitset2) _bitsetPool_set(_bitset1) _bitsetPool_set(_bitset2) if intersect: return True return False
def _intersects(bitset1, bitset2): for dat in range(bitset1._data._data.length): data1 = bitset1._data._data data2 = bitset2._data._data intersect = data1[dat] & data2[dat] if intersect: return True return False
def __init__(self, imagedata): self._imagedata = ImageData(imagedata) array = Ndarray(self._imagedata.data) array.setshape(self._imagedata.height, self._imagedata.width, 4) try: data = Uint8ClampedArray(self._imagedata.height * self._imagedata.width) except NotImplementedError: data = Uint8Array(self._imagedata.height * self._imagedata.width) index = 0 for x in range(self._imagedata.width): for y in range(self._imagedata.height): data[index] = array[y, x, 3] index += 1 try: Ndarray.__init__(self, data, 'uint8c') except NotImplementedError: Ndarray.__init__(self, data, 'uint8') self.setshape(self._imagedata.width, self._imagedata.height)
def from_surface(surface, threshold=127): """ **pyjsdl.mask.from_surface** Return Mask derived from surface using alpha transparency. Optional argument to set alpha threshold. """ mask = Mask((surface.width, surface.height)) if not mask.bit: return None pixels = surface.impl.getImageData(0, 0, surface.width, surface.height) width, height = surface.width*4, surface.height for y in range(0, height): xpix = 0 i = (y*width)+3 for x in range(0, width, 4): if surface._getPixel(pixels, i+x) > threshold: mask.set_at((xpix,y)) xpix += 1 return mask
def __init__(self, size): """ Return a Mask object. The size argument is (width, height) of the mask. The mask is represented by a list of Bitset. """ self.width = int(size[0]) self.height = int(size[1]) self.bit = [] for bitset in range(self.height): self.bit.append(BitSet(self.width))
def toString(self, bit=('1', '0')): """ Return string representation of mask. Optional bit argument specify bit character. """ cbit = {True: bit[0], False: bit[1]} cbitset = [] for bitset in self.bit: cbitset.append('\n') cbitset.extend([cbit[bitset.get(i)] for i in range(self.width)]) bitstr = ''.join(cbitset) return bitstr
def replace_color(self, color, new_color=None): """ Replace color with with new_color or with alpha. """ pixels = self.impl.getImageData(0, 0, self.width, self.height) if hasattr(color, 'a'): color1 = color else: color1 = Color(color) if new_color is None: alpha_zero = True else: if hasattr(new_color, 'a'): color2 = new_color else: color2 = Color(new_color) alpha_zero = False if alpha_zero: r1, g1, b1, a1 = color1.r, color1.g, color1.b, color1.a a2 = 0 for i in range(0, len(pixels.data), 4): if (self._getPixel(pixels, i) == r1 and self._getPixel(pixels, i + 1) == g1 and self._getPixel(pixels, i + 2) == b1 and self._getPixel(pixels, i + 3) == a1): self._setPixel(pixels, i + 3, a2) else: r1, g1, b1, a1 = color1.r, color1.g, color1.b, color1.a r2, g2, b2, a2 = color2.r, color2.g, color2.b, color2.a for i in range(0, len(pixels.data), 4): if (self._getPixel(pixels, i) == r1 and self._getPixel(pixels, i + 1) == g1 and self._getPixel(pixels, i + 2) == b1 and self._getPixel(pixels, i + 3) == a1): self._setPixel(pixels, i, r2) self._setPixel(pixels, i + 1, g2) self._setPixel(pixels, i + 2, b2) self._setPixel(pixels, i + 3, a2) self.impl.putImageData(pixels, 0, 0, 0, 0, self.width, self.height) return None
def _bitset_get(bitset, index, toIndex): data = bitset._data._data _bitset = _bitsetPool_get(toIndex - index) ix = 0 if toIndex > bitset._width: toIndex = bitset._width for i in range(index, toIndex): _bitset_set( _bitset, ix, bool(data[int(i / bitset._bit)] & bitset._bitmask[i % bitset._bit])) ix += 1 return _bitset
def replace_color(self, color, new_color=None): """ Replace color with with new_color or with alpha. """ pixels = self.getImageData(0, 0, self.width, self.height) if hasattr(color, 'a'): color1 = color else: color1 = Color(color) if new_color is None: alpha_zero = True else: if hasattr(new_color, 'a'): color2 = new_color else: color2 = Color(new_color) alpha_zero = False if alpha_zero: r1, g1, b1, a1 = color1.r, color1.g, color1.b, color1.a a2 = 0 data = pixels.data for i in range(0, len(data), 4): if (data[i] == r1 and data[i + 1] == g1 and data[i + 2] == b1 and data[i + 3] == a1): data[i + 3] = a2 else: r1, g1, b1, a1 = color1.r, color1.g, color1.b, color1.a r2, g2, b2, a2 = color2.r, color2.g, color2.b, color2.a data = pixels.data for i in range(0, len(data), 4): if (data[i] == r1 and data[i + 1] == g1 and data[i + 2] == b1 and data[i + 3] == a1): data[i] = r2 data[i + 1] = g2 data[i + 2] = b2 data[i + 3] = a2 self.putImageData(pixels, 0, 0, 0, 0, self.width, self.height) return None
def overlap(self, mask, offset): """ Return True if mask at offset position overlap with this mask. """ if offset[0] > 0: x1 = offset[0] x2 = 0 else: x1 = 0 x2 = -offset[0] if offset[1] > 0: y1 = offset[1] y2 = 0 else: y1 = 0 y2 = -offset[1] w = min(self.width - x1, mask.width - x2) h = min(self.height - y1, mask.height - y2) if w > 0 and h > 0: for y in range(h): if self.bit[y1 + y].get(x1, x1 + w).intersects( mask.bit[y2 + y].get(x2, x2 + w)): return True return None
def _bitsetPool_set(bitset): data = bitset._data._data for i in range(data.length): data[i] = 0 _bitsetPool[bitset._width].append(bitset)