def testWithString(self): pm1 = QPixmap() ok = QPixmapCache.find('img', pm1) self.assertFalse(ok) self.assertEqual(QPixmapCache.find('img'), None) pm2 = QPixmap() ok = QPixmapCache.insert('img', pm2) self.assertTrue(ok) pm3 = QPixmap() ok = QPixmapCache.find('img', pm3) self.assertTrue(ok) b1 = QPixmapCache.find('img').toImage().bits() b2 = pm3.toImage().bits() self.assertEqual(QPixmapCache.find('img').toImage().bits(), pm3.toImage().bits())
def testWithString(self): pm1 = QPixmap() ok = QPixmapCache.find('img', pm1) self.assertFalse(ok) self.assertEqual(QPixmapCache.find('img'), None) pm2 = QPixmap() ok = QPixmapCache.insert('img', pm2) self.assertTrue(ok) pm3 = QPixmap() ok = QPixmapCache.find('img', pm3) self.assertTrue(ok) b1 = QPixmapCache.find('img').toImage().bits() b2 = pm3.toImage().bits() self.assertEqual( QPixmapCache.find('img').toImage().bits(), pm3.toImage().bits())
class QPixmapQDatastream(UsesQApplication): '''QDataStream <<>> QPixmap''' def setUp(self): super(QPixmapQDatastream, self).setUp() self.source_pixmap = QPixmap(100, 100) self.source_pixmap.fill(Qt.red) self.output_pixmap = QPixmap() self.buffer = QByteArray() self.read_stream = QDataStream(self.buffer, QIODevice.ReadOnly) self.write_stream = QDataStream(self.buffer, QIODevice.WriteOnly) def testStream(self): self.write_stream << self.source_pixmap self.read_stream >> self.output_pixmap image = self.output_pixmap.toImage() pixel = image.pixel(10, 10) self.assertEqual(pixel, QColor(Qt.red).rgba()) self.assertEqual(self.source_pixmap.toImage(), self.output_pixmap.toImage())
class QPixmapQDatastream(UsesQApplication): '''QDataStream <<>> QPixmap''' def setUp(self): super(QPixmapQDatastream, self).setUp() self.source_pixmap = QPixmap(100, 100) self.source_pixmap.fill(Qt.red) self.output_pixmap = QPixmap() self.buffer = QByteArray() self.read_stream = QDataStream(self.buffer, QIODevice.ReadOnly) self.write_stream = QDataStream(self.buffer, QIODevice.WriteOnly) def testStream(self): self.write_stream << self.source_pixmap self.read_stream >> self.output_pixmap image = self.output_pixmap.toImage() pixel = image.pixel(10,10) self.assertEqual(pixel, QColor(Qt.red).rgba()) self.assertEqual(self.source_pixmap.toImage(), self.output_pixmap.toImage())
def testWithKey(self): pm1 = QPixmap() ok = QPixmapCache.find(QPixmapCache.Key(), pm1) self.assertFalse(ok) self.assertEqual(QPixmapCache.find(QPixmapCache.Key()), None) pm2 = QPixmap() key = QPixmapCache.insert(pm2) pm3 = QPixmap() ok = QPixmapCache.find(key, pm3) self.assertTrue(ok) self.assertEqual(QPixmapCache.find(key).toImage().bits(), pm3.toImage().bits())
def testWithKey(self): pm1 = QPixmap() ok = QPixmapCache.find(QPixmapCache.Key(), pm1) self.assertFalse(ok) self.assertEqual(QPixmapCache.find(QPixmapCache.Key()), None) pm2 = QPixmap() key = QPixmapCache.insert(pm2) pm3 = QPixmap() ok = QPixmapCache.find(key, pm3) self.assertTrue(ok) self.assertEqual( QPixmapCache.find(key).toImage().bits(), pm3.toImage().bits())
def tag_image(source, dest, tag, font, fontsize, x, y, width, height, aspectx, aspecty, red, green, blue, bold=False, italic=False): """docstring for tag_image""" app = QApplication.instance() pixmap = QPixmap(source) color = QColor(red,green,blue) font = QFont(font) font.setPixelSize(int(fontsize*pixmap.height())) font.setItalic(italic) font.setBold(bold) painter = QPainter(pixmap) painter.setPen(color) painter.setFont(font); painter.drawText(x*pixmap.width(),y*pixmap.height(), tag) painter.end() # Resize and save return pixmap.toImage().scaled(width*aspectx, height*aspecty, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation).scaled(width, height, Qt.IgnoreAspectRatio, Qt.SmoothTransformation).save(dest)
class ImagePreset(RawPreset): def setup(self): self.add_parameter(FloatParameter('speed-rotation', 0.1)) self.add_parameter(FloatParameter('speed-hue', 0.0)) self.add_parameter(FloatParameter('center-orbit-distance', 0.0)) self.add_parameter(FloatParameter('center-orbit-speed', 0.1)) self.add_parameter(StringParameter('image-file', "")) self.add_parameter(StringParameter('edge-mode', "clamp")) # mirror, tile, clamp self.add_parameter(FloatParameter('center-x', 0.0)) self.add_parameter(FloatParameter('center-y', 0.0)) self.add_parameter(FloatParameter('scale', 1.0)) self.add_parameter(FloatParameter('ghost', 0.0)) self.add_parameter(FloatParameter('beat-lum-boost', 0.1)) self.add_parameter(FloatParameter('beat-lum-time', 0.05)) self.pixel_locations = self.scene().get_all_pixel_locations() self.hue_inner = random.random() + 100 self._center_rotation = random.random() self.angle = 0 self.lum_boost = 0 self.hue_offset = 0 self.imagename = None self.image = None self._buffer = None self.parameter_changed(None) def parameter_changed(self, parameter): if self.imagename != self.parameter('image-file').get(): self.pixmap = QPixmap(self.parameter('image-file').get()) self.imagename = self.parameter('image-file').get() image = self.pixmap.toImage() if image: #image = image.convertToFormat(QImage.Format_ARGB32) self.image = np.frombuffer(image.bits(), dtype=np.uint8) self.image = self.image.reshape(self.pixmap.height(), self.pixmap.width(), 4).T self.image = np.asarray( (self.image[2], self.image[1], self.image[0])).T self.image = rgb_to_hls(self.image) #print self.image print "image", self.parameter( 'image-file').get(), "loaded:", self.image.shape self.lastFrame = None def reset(self): pass def draw(self, dt): if self.pixmap: lum_boost = self.parameter('beat-lum-boost').get() if self._mixer.is_onset(): self.lum_boost += lum_boost self.hue_offset += dt * self.parameter('speed-hue').get() self._center_rotation += dt * self.parameter( 'center-orbit-speed').get() self.angle += dt * self.parameter('speed-rotation').get() orbitx = math.cos(self._center_rotation) * self.parameter( 'center-orbit-distance').get() orbity = math.sin(self._center_rotation) * self.parameter( 'center-orbit-distance').get() locations = np.copy(self.pixel_locations.T) cx, cy = self.scene().center_point() locations[0] -= cx + orbitx locations[1] -= cy + orbity rotMatrix = np.array([ (math.cos(self.angle), -math.sin(self.angle)), (math.sin(self.angle), math.cos(self.angle)) ]) x, y = rotMatrix.T.dot(locations) x /= self.parameter('scale').get() y /= self.parameter('scale').get() x += self.pixmap.width() / 2 + self.parameter('center-x').get() y += self.pixmap.height() / 2 + self.parameter('center-y').get() x = np.int_(x) y = np.int_(y) edge_mode = self.parameter('edge-mode').get() if edge_mode == "clamp": np.clip(x, 0, self.pixmap.width() - 1, x) np.clip(y, 0, self.pixmap.height() - 1, y) elif edge_mode == "tile": np.mod(np.abs(x), self.pixmap.width(), x) np.mod(np.abs(y), self.pixmap.height(), y) elif edge_mode == "mirror": np.mod(np.abs(x), self.pixmap.width() * 2 - 1, x) np.mod(np.abs(y), self.pixmap.height() * 2 - 1, y) np.abs(x - (self.pixmap.width() - 1), x) np.abs(y - (self.pixmap.height() - 1), y) else: print "Unknown image preset edge mode (clamp, tile, or mirror)." locations = np.asarray([x, y]).T colors = self.image[locations.T[1], locations.T[0]] colors.T[0] += self.hue_offset colors.T[1] += self.lum_boost ghost = self.parameter('ghost').get() if abs(ghost) > 0: if self.lastFrame != None: if self._buffer is None: self._buffer = np.empty_like(self.lastFrame) colors = hls_blend(colors, self.lastFrame, self._buffer, ghost, "add", 1.0, 0.1) self.lastFrame = colors lum_time = self.parameter('beat-lum-time').get() if lum_time and self.lum_boost: if self.lum_boost > 0: self.lum_boost = max( 0, self.lum_boost - lum_boost * dt / lum_time) else: self.lum_boost = min( 0, self.lum_boost - lum_boost * dt / lum_time) self._pixel_buffer = colors
class ImagePattern(Pattern): def setup(self): self.add_parameter(FloatParameter('speed-rotation', 0.1)) self.add_parameter(FloatParameter('speed-hue', 0.0)) self.add_parameter(FloatParameter('center-orbit-distance', 0.0)) self.add_parameter(FloatParameter('center-orbit-speed', 0.1)) self.add_parameter(StringParameter('image-file', "")) self.add_parameter(StringParameter('edge-mode', "clamp")) # mirror, tile, clamp self.add_parameter(FloatParameter('center-x', 0.0)) self.add_parameter(FloatParameter('center-y', 0.0)) self.add_parameter(FloatParameter('scale', 1.0)) self.add_parameter(FloatParameter('ghost', 0.0)) self.add_parameter(FloatParameter('beat-lum-boost', 0.1)) self.add_parameter(FloatParameter('beat-lum-time', 0.05)) self.pixel_locations = self.scene().get_all_pixel_locations() self.hue_inner = random.random() + 100 self._center_rotation = random.random() self.angle = 0 self.lum_boost = 0 self.hue_offset = 0 self.imagename = None self.image = None self._buffer = None def parameter_changed(self, parameter): if self.imagename != self.parameter('image-file').get(): self.pixmap = QPixmap(self.parameter('image-file').get()) self.imagename = self.parameter('image-file').get() image = self.pixmap.toImage() if image: #image = image.convertToFormat(QImage.Format_ARGB32) self.image = np.frombuffer(image.bits(), dtype=np.uint8) self.image = self.image.reshape(self.pixmap.height(), self.pixmap.width(), 4).T self.image = np.asarray((self.image[2],self.image[1],self.image[0])).T self.image = rgb_to_hls(self.image) print self.image #print "image", self.parameter('image-file').get(), "loaded:", self.image.shape else: print "No image!" self.lastFrame = None def reset(self): pass def draw(self, dt): if self.pixmap: lum_boost = self.parameter('beat-lum-boost').get() if self._app.mixer.is_onset(): self.lum_boost += lum_boost self.hue_offset += dt * self.parameter('speed-hue').get() self._center_rotation += dt * self.parameter('center-orbit-speed').get() self.angle += dt * self.parameter('speed-rotation').get() orbitx = math.cos(self._center_rotation) * self.parameter('center-orbit-distance').get() orbity = math.sin(self._center_rotation) * self.parameter('center-orbit-distance').get() locations = np.copy(self.pixel_locations.T) cx, cy = self.scene().center_point() locations[0] -= cx + orbitx locations[1] -= cy + orbity rotMatrix = np.array([(math.cos(self.angle), -math.sin(self.angle)), (math.sin(self.angle), math.cos(self.angle))]) x,y = rotMatrix.T.dot(locations) x /= self.parameter('scale').get() y /= self.parameter('scale').get() x += self.pixmap.width() / 2 + self.parameter('center-x').get() y += self.pixmap.height() / 2 + self.parameter('center-y').get() x = np.int_(x) y = np.int_(y) edge_mode = self.parameter('edge-mode').get() if edge_mode == "clamp": np.clip(x, 0, self.pixmap.width() - 1, x) np.clip(y, 0, self.pixmap.height() - 1, y) elif edge_mode == "tile": np.mod(np.abs(x), self.pixmap.width(), x) np.mod(np.abs(y), self.pixmap.height(), y) elif edge_mode == "mirror": np.mod(np.abs(x), self.pixmap.width() * 2 - 1, x) np.mod(np.abs(y), self.pixmap.height() * 2 - 1, y) np.abs(x - (self.pixmap.width() - 1), x) np.abs(y - (self.pixmap.height() - 1), y) else: print "Unknown image preset edge mode (clamp, tile, or mirror)." locations = np.asarray([x,y]).T colors = self.image[locations.T[1], locations.T[0]] colors.T[0] += self.hue_offset colors.T[1] += self.lum_boost ghost = self.parameter('ghost').get() if abs(ghost) > 0: if self.lastFrame != None: if self._buffer is None: self._buffer = np.empty_like(self.lastFrame) colors = hls_blend(colors, self.lastFrame, self._buffer, ghost, "add", 1.0, 0.1) self.lastFrame = colors lum_time = self.parameter('beat-lum-time').get() if lum_time and self.lum_boost: if self.lum_boost > 0: self.lum_boost = max(0, self.lum_boost - lum_boost * dt / lum_time) else: self.lum_boost = min(0, self.lum_boost - lum_boost * dt / lum_time) self._pixel_buffer = colors
class Fourier(QWidget): """ Actual fourier display and drawing widget """ fourier_updated = Signal(np.ndarray) image = None pressed = False scale_factor = None color = QColor(0, 0, 0) raw_fourier = None x_sym = False y_sym = False opp_sym = False # signal fourier updated def __init__(self, parent=None): super().__init__(parent) self.update_cursor('square', 20) self.overlay = Overlay(self) def update_image(self, fft_array, factor=None): scaled_values, sf = rescale_array(np.real(np.log2(fft_array)), self.scale_factor) self.scale_factor = sf self.image = array_to_image(scaled_values) self.setMinimumSize(self.image.size()) self.overlay.resize(self.image.size()) self.update() self.updateGeometry() # I have to deliver, and it's broken on windows. self.setMinimumSize(self.image.size()) self.overlay.resize(self.image.size()) self.update() self.updateGeometry() def update_fourier(self, image_array, flush=False): f = array_to_fft(image_array) if self.raw_fourier is None or flush: self.original = f.copy() self.raw_fourier = f.copy() self.update_image(self.raw_fourier) def update_cursor(self, shape, size): self.cursor_size = size self.shape = shape cursor_pix = QPixmap(size, size) cursor_pix.fill(Qt.transparent) painter = QPainter(cursor_pix) painter.setPen(QColor(255, 0, 0)) if shape == 'circle': painter.drawEllipse(0, 0, size - 1, size - 1) elif shape == 'square': painter.drawRect(0, 0, size - 1, size - 1) elif shape == "magic wand": magic_wand.render(painter, QRect(0, 0, 20, 20)) cursor = QCursor(cursor_pix, 0, 0) self.setCursor(cursor) del painter def on_size_change(self, size): """ Brush size changed """ self.cursor_size = size self.update_cursor(self.shape, self.cursor_size) Slot(str) def on_shape_change(self, shape): """ Brush shape changed """ self.shape = shape self.update_cursor(self.shape, self.cursor_size) def on_color_change(self, color): self.color = QColor(color, color, color) def emit_fourier(self): array = fft_to_array(self.raw_fourier) self.fourier_updated.emit(array) def on_restore(self): self.raw_fourier = self.original.copy() self.update_image(self.raw_fourier, self.scale_factor) #self.fourier_updated.emit(self.raw_fourier.copy()) self.emit_fourier() def on_resize(self, factor): if factor == 1.0: return #even = lambda x: x if (x % 2 == 0) else x + 1 array = self.raw_fourier reshape = lambda x_y: [int(factor * x_y[0]), int(factor * x_y[1])] diff = lambda x_y: [x_y[0] - array.shape[0], x_y[1] - array.shape[1]] nexteven = lambda x: x if (x % 2 == 0) else x + 1 delta = map(nexteven, diff(reshape(array.shape))) newsize = tuple(x[0] + x[1] for x in zip(array.shape, delta)) self.raw_fourier = zeropad(array, newsize) self.update_image(self.raw_fourier, self.scale_factor) #self.fourier_updated.emit(self.raw_fourier.copy()) self.emit_fourier() def draw_mask_on_fourier(self, mask, value=0x00): self.raw_fourier[mask] = 2**value self.update_image(self.raw_fourier, self.scale_factor) self.emit_fourier() def regen_image(self): self.update_image(self.raw_fourier, self.scale_factor) def paintEvent(self, event): """ Paint widget as self.image content """ if self.image is None: super().paintEvent(event) return painter = QPainter(self) rect = event.rect() painter.drawImage(rect.topLeft(), self.image, rect) def mousePressEvent(self, event): self.pressed = True self.draw_buffer = QPixmap(self.image.size()) color = self.color.red() ^ 0xAA self.draw_buffer.fill(QColor(color, color, color)) self.draw(event) def mouseReleaseEvent(self, event): self.pressed = False self.draw(event) self.fourier_draw() def mouseMoveEvent(self, event): if self.pressed: self.draw(event) def fourier_draw(self): arr = image_to_array(self.draw_buffer.toImage()) values = arr[arr == self.color.red()] * (self.scale_factor / 255) self.raw_fourier[arr == self.color.red()] = np.abs(2**values) self.emit_fourier() def _paint(self, painter, x, y): size = self.cursor_size shape = self.shape painter.setBrush(self.color) painter.setPen(Qt.NoPen) if shape == 'circle': painter.drawEllipse(x, y, size - 1, size - 1) elif shape == 'square': painter.drawRect(x, y, size - 1, size - 1) elif shape == "magic wand": magic_wand.render(painter, QRect(0, 0, 20, 20)) def draw(self, event): x, y = event.x(), event.y() max_y, max_x = self.raw_fourier.shape for painter in map(QPainter, [self.image, self.draw_buffer]): self._paint(painter, x, y) if self.x_sym: self._paint(painter, abs(max_x - x - self.cursor_size), y) if self.y_sym: self._paint(painter, x, abs(max_y - y - self.cursor_size)) if (self.x_sym and self.y_sym) or self.opp_sym: self._paint(painter, abs(max_x - x - self.cursor_size), abs(max_y - y - self.cursor_size)) del painter self.update() def sizeHint(self): if not self.image: return super().minimumSizeHint() return self.image.size() def on_y_toggle(self, y_state): self.y_sym = y_state def on_x_toggle(self, x_state): self.x_sym = x_state def on_opp_toggle(self, opp_state): self.opp_sym = opp_state