def applycolors(data, pal): if args.PC: for color in pal: data.append(qBlue(color)) data.append(qGreen(color)) data.append(qRed(color)) data.append(qAlpha(color)) else: for color in pal: data.append(qRed(color)) data.append(qGreen(color)) data.append(qBlue(color)) data.append(qAlpha(color)) return data
def get_indexed(data, w, h, colors=256, crop=True): palette = data[:colors * 4] table = [] for i in range(colors): b = palette[(i * 4) + 0] g = palette[(i * 4) + 1] r = palette[(i * 4) + 2] a = palette[(i * 4) + 3] table.append(qRgba(r, g, b, a)) img_start = colors * 4 mask_start = img_start + (w * h) image = data[img_start:mask_start] image = QImage(image, w, h, QImage.Format_Indexed8) image.setColorTable(table) image = image.convertToFormat(QImage.Format_ARGB32) mask = data[mask_start:] for i in range(len(mask)): x = i % w y = i / w pixel = image.pixel(x, y) pixel = qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), mask[i]) image.setPixel(x, y, pixel) if crop: image = image.copy(0, 0, w - 2, h - 2) return image, len(mask) > 0
def qimageToRaster(img, fileName, xMin=0, yMax=0, mupp=1, crsWkt=None): """ Use GDAL to turn a QImage to GeoTIFF file """ driver = gdal.GetDriverByName("GTiff") ds = driver.Create(fileName, img.width(), img.height(), 4, gdal.GDT_Byte, ['ALPHA=YES']) # setup affine transform ds.SetGeoTransform([ xMin, mupp, 0, yMax, 0, -mupp ]) if crsWkt is not None: ds.SetProjection(str(crsWkt)) size = img.height(), img.width() raster_r = numpy.zeros(size, dtype=numpy.uint8) raster_g = numpy.zeros(size, dtype=numpy.uint8) raster_b = numpy.zeros(size, dtype=numpy.uint8) raster_a = numpy.zeros(size, dtype=numpy.uint8) for i in xrange(img.width()*img.height()): x,y = i % img.width(), i / img.width() rgb = img.pixel(x,y) raster_r[y,x], raster_g[y,x], raster_b[y,x], raster_a[y,x] = qRed(rgb), qGreen(rgb), qBlue(rgb), qAlpha(rgb) ds.GetRasterBand(1).WriteArray(raster_r) ds.GetRasterBand(2).WriteArray(raster_g) ds.GetRasterBand(3).WriteArray(raster_b) ds.GetRasterBand(4).WriteArray(raster_a) ds = None # Once we're done, close properly the dataset
def updateMask(control_image_path, rendered_image_path, mask_image_path): control_image = imageFromPath(control_image_path) if not control_image: error('Could not read control image {}'.format(control_image_path)) rendered_image = imageFromPath(rendered_image_path) if not rendered_image: error('Could not read rendered image {}'.format(rendered_image_path)) if not rendered_image.width() == control_image.width( ) or not rendered_image.height() == control_image.height(): print( 'Size mismatch - control image is {}x{}, rendered image is {}x{}'. format(control_image.width(), control_image.height(), rendered_image.width(), rendered_image.height())) max_width = min(rendered_image.width(), control_image.width()) max_height = min(rendered_image.height(), control_image.height()) #read current mask, if it exist mask_image = imageFromPath(mask_image_path) if mask_image.isNull(): print 'Mask image does not exist, creating {}'.format(mask_image_path) mask_image = QImage(control_image.width(), control_image.height(), QImage.Format_ARGB32) mask_image.fill(QColor(0, 0, 0)) #loop through pixels in rendered image and compare mismatch_count = 0 linebytes = max_width * 4 for y in xrange(max_height): control_scanline = control_image.constScanLine(y).asstring(linebytes) rendered_scanline = rendered_image.constScanLine(y).asstring(linebytes) mask_scanline = mask_image.scanLine(y).asstring(linebytes) for x in xrange(max_width): currentTolerance = qRed( struct.unpack('I', mask_scanline[x * 4:x * 4 + 4])[0]) if currentTolerance == 255: #ignore pixel continue expected_rgb = struct.unpack('I', control_scanline[x * 4:x * 4 + 4])[0] rendered_rgb = struct.unpack('I', rendered_scanline[x * 4:x * 4 + 4])[0] difference = colorDiff(expected_rgb, rendered_rgb) if difference > currentTolerance: #update mask image mask_image.setPixel(x, y, qRgb(difference, difference, difference)) mismatch_count += 1 if mismatch_count: #update mask mask_image.save(mask_image_path, "png") print 'Updated {} pixels in {}'.format(mismatch_count, mask_image_path) else: print 'No mismatches in {}'.format(mask_image_path)
def qimageToRaster(img, fileName, xMin=0, yMax=0, mupp=1, crsWkt=None): """ Use GDAL to turn a QImage to GeoTIFF file """ driver = gdal.GetDriverByName("GTiff") ds = driver.Create(fileName, img.width(), img.height(), 4, gdal.GDT_Byte, ['ALPHA=YES']) # setup affine transform ds.SetGeoTransform([xMin, mupp, 0, yMax, 0, -mupp]) if crsWkt is not None: ds.SetProjection(str(crsWkt)) size = img.height(), img.width() raster_r = numpy.zeros(size, dtype=numpy.uint8) raster_g = numpy.zeros(size, dtype=numpy.uint8) raster_b = numpy.zeros(size, dtype=numpy.uint8) raster_a = numpy.zeros(size, dtype=numpy.uint8) for i in xrange(img.width() * img.height()): x, y = i % img.width(), i / img.width() rgb = img.pixel(x, y) raster_r[y, x], raster_g[y, x], raster_b[y, x], raster_a[y, x] = qRed( rgb), qGreen(rgb), qBlue(rgb), qAlpha(rgb) ds.GetRasterBand(1).WriteArray(raster_r) ds.GetRasterBand(2).WriteArray(raster_g) ds.GetRasterBand(3).WriteArray(raster_b) ds.GetRasterBand(4).WriteArray(raster_a) ds = None # Once we're done, close properly the dataset
def to_SHTXFs(img): data = bytearray(SHTXFs_MAGIC) width = img.width() height = img.height() data.extend(from_u16(width)) data.extend(from_u16(height)) data.append(int(math.ceil(math.log(width, 2)))) data.append(int(math.ceil(math.log(height, 2)))) pal = img.colorTable() if len(pal) < 256: pal.extend([0] * (256 - len(pal))) for color in pal: data.append(qRed(color)) data.append(qGreen(color)) data.append(qBlue(color)) data.append(qAlpha(color)) data.extend(img.constBits().asstring(width * height)) return data
def data(fn): img = QImage(fn) d = np.zeros((img.width(), img.height(), 3)) for i in xrange(img.width()): for j in xrange(img.height()): raw_col = img.pixel(i, j) d[i, j][0] = qRed(raw_col) d[i, j][1] = qGreen(raw_col) d[i, j][2] = qBlue(raw_col) return d
def updateMask(control_image_path, rendered_image_path, mask_image_path): control_image = imageFromPath(control_image_path) if not control_image: error('Could not read control image {}'.format(control_image_path)) rendered_image = imageFromPath(rendered_image_path) if not rendered_image: error('Could not read rendered image {}'.format(rendered_image_path)) if not rendered_image.width() == control_image.width() or not rendered_image.height() == control_image.height(): print ('Size mismatch - control image is {}x{}, rendered image is {}x{}'.format(control_image.width(), control_image.height(), rendered_image.width(), rendered_image.height())) max_width = min(rendered_image.width(), control_image.width()) max_height = min(rendered_image.height(), control_image.height()) #read current mask, if it exist mask_image = imageFromPath(mask_image_path) if mask_image.isNull(): print 'Mask image does not exist, creating {}'.format(mask_image_path) mask_image = QImage(control_image.width(), control_image.height(), QImage.Format_ARGB32) mask_image.fill(QColor(0, 0, 0)) #loop through pixels in rendered image and compare mismatch_count = 0 linebytes = max_width * 4 for y in xrange(max_height): control_scanline = control_image.constScanLine(y).asstring(linebytes) rendered_scanline = rendered_image.constScanLine(y).asstring(linebytes) mask_scanline = mask_image.scanLine(y).asstring(linebytes) for x in xrange(max_width): currentTolerance = qRed(struct.unpack('I', mask_scanline[x * 4:x * 4 + 4])[0]) if currentTolerance == 255: #ignore pixel continue expected_rgb = struct.unpack('I', control_scanline[x * 4:x * 4 + 4])[0] rendered_rgb = struct.unpack('I', rendered_scanline[x * 4:x * 4 + 4])[0] difference = colorDiff(expected_rgb, rendered_rgb) if difference > currentTolerance: #update mask image mask_image.setPixel(x, y, qRgb(difference, difference, difference)) mismatch_count += 1 if mismatch_count: #update mask mask_image.save(mask_image_path, "png") print 'Updated {} pixels in {}'.format(mismatch_count, mask_image_path) else: print 'No mismatches in {}'.format(mask_image_path)
def blit(src, dst, x, y, masked): w = src.width() h = src.height() out = dst.copy() for i in range(w): for j in range(h): dst_pixel = dst.pixel(x + i, y + j) src_pixel = src.pixel(i, j) # If src has transparency data, we use it, otherwise, we borrow from dst. # This logic doesn't quite work for bustup/l/si4? if masked or dst_pixel == TRANSPARENT_COLOR: out_pixel = src_pixel else: out_pixel = qRgba(qRed(src_pixel), qGreen(src_pixel), qBlue(src_pixel), qAlpha(dst_pixel)) out.setPixel(x + i, y + j, out_pixel) return out
def colorDiff(c1, c2): redDiff = abs(qRed(c1) - qRed(c2)) greenDiff = abs(qGreen(c1) - qGreen(c2)) blueDiff = abs(qBlue(c1) - qBlue(c2)) alphaDiff = abs(qAlpha(c1) - qAlpha(c2)) return max(redDiff, greenDiff, blueDiff, alphaDiff)
def toleranceMatch(self, px1, px2, rgbTolerances): if (abs(qRed(px1) - qRed(px2))) > rgbTolerances[0] or (abs(qGreen(px1) - qGreen(px2))) > rgbTolerances[1] or (abs(qBlue(px1) - qBlue(px2))) > rgbTolerances[2]: return False if not self.mw.ui.actionIgnore_Transparent_Pixels.isChecked(): return abs(qAlpha(px1) == qAlpha(px2)) return True
def writeText(fp, colorTable): for i in colorTable: print(u"{0}, {1}, {2},".format(qRed(i), qGreen(i), qBlue(i)), file=fp)
def render(self, image, depth, viewport_scale, stroke_colour): # Sort the edges of the polygon by their minimum projected y # coordinates, discarding horizontal edges. width = image.width() height = image.height() z_max = 1 << 16 edges = [] l = len(self.points) for i in range(l): pxa, pya = self.projected[i] pxa = width / 2 + (pxa * viewport_scale) pya = height / 2 - (pya * viewport_scale) za = -self.points[i].z j = (i + 1) % l pxb, pyb = self.projected[j] pxb = width / 2 + (pxb * viewport_scale) pyb = height / 2 - (pyb * viewport_scale) zb = -self.points[j].z # Append the starting and finishing y coordinates, the starting # x coordinate, the dx/dy gradient of the edge, the starting # z coordinate and the dz/dy gradient of the edge. if int(pya) < int(pyb): edges.append((pya, pyb, pxa, (pxb - pxa) / (pyb - pya), za, (zb - za) / (pyb - pya))) elif int(pya) > int(pyb): edges.append((pyb, pya, pxb, (pxa - pxb) / (pya - pyb), zb, (za - zb) / (pya - pyb))) if not edges: return edges.sort() end_py = edges[-1][1] if end_py < 0: return py1, end_py1, px1, dx1, z1, dz1 = edges.pop(0) if py1 >= height: return py2, end_py2, px2, dx2, z2, dz2 = edges.pop(0) py = int(py1) if py < py1 or py < py2: py += 1 while py <= end_py and py < height: # Retrieve new edges as required. if py >= end_py1: if not edges: break py1, end_py1, px1, dx1, z1, dz1 = edges.pop(0) if py >= end_py2: if not edges: break py2, end_py2, px2, dx2, z2, dz2 = edges.pop(0) if py < 0: py += 1 continue # Calculate the starting and finishing x coordinates of the span # at the current y coordinate. sx1 = px1 + dx1 * (py - py1) sx2 = px2 + dx2 * (py - py2) # Calculate the starting and finishing z coordinates of the span # at the current y coordinate. sz1 = z1 + dz1 * (py - py1) sz2 = z2 + dz2 * (py - py2) # Do not render the span if it lies outside the image or has # values that cannot be stored in the depth buffer. # Truncate the span if it lies partially within the image. if sx1 > sx2: sx1, sx2 = sx2, sx1 sz1, sz2 = sz2, sz1 # Only calculate a depth gradient for the span if it is more than # one pixel wide. if sx1 != sx2: dz = (sz2 - sz1) / (sx2 - sx1) else: dz = 0.0 if sz1 <= 0 and sz2 <= 0: py += 1 continue elif sz1 >= z_max and sz2 >= z_max: py += 1 continue sx, end_sx = int(sx1), int(sx2) if sx < sx1: sx += 1 if sx >= width: py += 1 continue elif end_sx < 0: py += 1 continue if sx < 0: sx = 0 if end_sx >= width: end_sx = width - 1 # Draw the span. while sx <= end_sx: sz = sz1 + dz * (sx - sx1) if 0 < sz <= depth[int(sx)][int(py)]: if self.alpha < 1.0: pixel = image.pixel(sx, py) dr = qRed(pixel) dg = qGreen(pixel) db = qBlue(pixel) r = (1 - self.alpha) * dr + self.alpha * self.red g = (1 - self.alpha) * dg + self.alpha * self.green b = (1 - self.alpha) * db + self.alpha * self.blue image.setPixel(sx, py, qRgb(r, g, b)) else: depth[int(sx)][int(py)] = sz image.setPixel(sx, py, self.rgba) sx += 1 if stroke_colour: if 0 <= sx1 < width and 0 < sz1 <= depth[int(sx1)][int(py)]: image.setPixel(sx1, py, stroke_colour) if 0 <= sx2 < width and 0 < sz2 <= depth[int(sx2)][int(py)]: image.setPixel(sx2, py, stroke_colour) py += 1