def _plat_get_blocks(self, block_count_per_side, orientation): image = QImage(str(self.path)) image = image.convertToFormat(QImage.Format_RGB888) # MYSTERY TO SOLVE: For reasons I cannot explain, orientations 5 and 7 don't work for # duplicate scanning. The transforms seems to work fine (if I try to save the image after # the transform, we see that the image has been correctly flipped and rotated), but the # analysis part yields wrong blocks. I spent enought time with this feature, so I'll leave # like that for now. (by the way, orientations 5 and 7 work fine under Cocoa) if 2 <= orientation <= 8: t = QTransform() if orientation == 2: t.scale(-1, 1) elif orientation == 3: t.rotate(180) elif orientation == 4: t.scale(1, -1) elif orientation == 5: t.scale(-1, 1) t.rotate(90) elif orientation == 6: t.rotate(90) elif orientation == 7: t.scale(-1, 1) t.rotate(270) elif orientation == 8: t.rotate(270) image = image.transformed(t) return getblocks(image, block_count_per_side)
def _updateImage(self): """ Retrieve a new image from Nao. """ self._alImage = self._videoProxy.getImageRemote(self._imgClient) self._image = QImage(self._alImage[6], self._alImage[0], self._alImage[1], QImage.Format_RGB888) self._image = QImage.convertToFormat(self._image, QImage.Format_RGB32) self.count += 1 if self.count == 1 or len(self.faces) == 0: self.face() cv2.imshow("nao", self._array) #comment out from here k = cv2.waitKey(100) & 0xff if k==27: cv2.destroyAllWindows() sys.exit(app.exec_()) #to here if you want to just use QApplications else: self.convertToCV() self.cShift() cv2.imshow("nao", self._array) #also comment out from here k = cv2.waitKey(100) & 0xff if k==27: cv2.destroyAllWindows() sys.exit(app.exec_()) #to here self.convertToQImage() self._array = cv2.cvtColor(self._array, cv2.COLOR_HSV2BGR)
def drawThreshMask(self, worm_img, worm_qimg, row_data, read_center=True): min_mask_area = row_data['area'] / 2 c1, c2 = (row_data['coord_x'], row_data['coord_y']) if read_center else (-1, -1) worm_mask, _ , _ = getWormMask(worm_img, row_data['threshold'], strel_size = self.strel_size, \ roi_center_x = c1, roi_center_y = c2, min_mask_area = min_mask_area) #worm_mask = np.zeros_like(worm_mask) #cv2.drawContours(worm_mask, [worm_cnt.astype(np.int32)], 0, 1, -1) worm_mask = QImage(worm_mask.data, worm_mask.shape[1], worm_mask.shape[0], worm_mask.strides[0], QImage.Format_Indexed8) worm_mask = worm_mask.convertToFormat(QImage.Format_RGB32, Qt.AutoColor) worm_mask = worm_mask.scaled(worm_qimg.width(), worm_qimg.height(), Qt.KeepAspectRatio) worm_mask = QPixmap.fromImage(worm_mask) worm_mask = worm_mask.createMaskFromColor(Qt.black) p = QPainter(worm_qimg) p.setPen(QColor(0, 204, 102)) p.drawPixmap(worm_qimg.rect(), worm_mask, worm_mask.rect()) p.end()
def basefinished(self): if self.basereply.error() != QNetworkReply.NoError: return self.basepixmap = QPixmap() self.basepixmap.loadFromData(self.basereply.readAll()) if self.basepixmap.size() != self.rect.size(): self.basepixmap = self.basepixmap.scaled(self.rect.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.setPixmap(self.basepixmap) # make marker pixmap self.mkpixmap = QPixmap(self.basepixmap.size()) self.mkpixmap.fill(Qt.transparent) br = QBrush(QColor(Config.dimcolor)) painter = QPainter() painter.begin(self.mkpixmap) painter.fillRect(0, 0, self.mkpixmap.width(), self.mkpixmap.height(), br) for marker in self.radar['markers']: if 'visible' not in marker or marker['visible'] == 1: pt = getPoint(marker["location"], self.point, self.zoom, self.rect.width(), self.rect.height()) mk2 = QImage() mkfile = 'teardrop' if 'image' in marker: mkfile = marker['image'] if os.path.dirname(mkfile) == '': mkfile = os.path.join('markers', mkfile) if os.path.splitext(mkfile)[1] == '': mkfile += '.png' mk2.load(mkfile) if mk2.format != QImage.Format_ARGB32: mk2 = mk2.convertToFormat(QImage.Format_ARGB32) mkh = 80 # self.rect.height() / 5 if 'size' in marker: if marker['size'] == 'small': mkh = 64 if marker['size'] == 'mid': mkh = 70 if marker['size'] == 'tiny': mkh = 40 if 'color' in marker: c = QColor(marker['color']) (cr, cg, cb, ca) = c.getRgbF() for x in range(0, mk2.width()): for y in range(0, mk2.height()): (r, g, b, a) = QColor.fromRgba(mk2.pixel(x, y)).getRgbF() r = r * cr g = g * cg b = b * cb mk2.setPixel(x, y, QColor.fromRgbF(r, g, b, a).rgba()) mk2 = mk2.scaledToHeight(mkh, 1) painter.drawImage(pt.x - mkh / 2, pt.y - mkh / 2, mk2) painter.end() self.wmk.setPixmap(self.mkpixmap)
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 draw_anagram(anagram): BOX_LEFT = 4 BOX_TOP = 22 BOX_X_OFFSET = 31 BOX_Y_OFFSET = 61 TEXT_X_OFFSET = 13 TEXT_Y_OFFSET = 9 TEXT_CLT = 8 FONT = CLT[TEXT_CLT]['font'] MAX_LETTERS = 15 BOX = QImage(os.path.join(ANAGRAM_DIR, "box.png")) QUESTION = QImage(os.path.join(ANAGRAM_DIR, "question.png")) out = QImage(os.path.join(ANAGRAM_DIR, "bg.png")) text = anagram.solution.translated if len(text) == 0: return out if not out.format() is QImage.Format_ARGB32_Premultiplied: out = out.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(out) painter.setRenderHint(QPainter.Antialiasing, True) # Put them in a list so it's easier to loop. visible = [range(1, len(text) + 1), anagram.easy, anagram.normal, anagram.hard] x = BOX_LEFT y = BOX_TOP for row in range(len(visible)): if not visible[row] == None: for i, char in enumerate(text): if (i + 1) in visible[row]: painter.drawImage(QRect(x, y, BOX.width(), BOX.height()), BOX, BOX.rect()) # Get info on our current letter. letter, (xshift, yshift, final_w, final_h) = get_letter(TEXT_CLT, char) painter.drawImage(QRect(x + TEXT_X_OFFSET + xshift, y + TEXT_Y_OFFSET + yshift, final_w, final_h), letter, letter.rect()) else: painter.drawImage(QRect(x, y, QUESTION.width(), QUESTION.height()), QUESTION, QUESTION.rect()) x += BOX_X_OFFSET x = BOX_LEFT y += BOX_Y_OFFSET painter.end() return out
def draw_anagram(anagram): BOX_LEFT = 4 BOX_TOP = 22 BOX_X_OFFSET = 31 BOX_Y_OFFSET = 61 TEXT_X_OFFSET = 13 TEXT_Y_OFFSET = 9 TEXT_CLT = 8 FONT = CLT_STYLES[TEXT_CLT].font MAX_LETTERS = 15 BOX = QImage(os.path.join(ANAGRAM_DIR, "box.png")) QUESTION = QImage(os.path.join(ANAGRAM_DIR, "question.png")) out = QImage(os.path.join(ANAGRAM_DIR, "bg.png")) text = anagram.solution[common.editor_config.lang_trans] if len(text) == 0: return out if not out.format() is QImage.Format_ARGB32_Premultiplied: out = out.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(out) painter.setRenderHint(QPainter.Antialiasing, True) # Put them in a list so it's easier to loop. visible = [range(1, len(text) + 1), anagram.easy, anagram.normal, anagram.hard] x = BOX_LEFT y = BOX_TOP for row in range(len(visible)): if not visible[row] == None: for i, char in enumerate(text): if (i + 1) in visible[row]: painter.drawImage(QRect(x, y, BOX.width(), BOX.height()), BOX, BOX.rect()) # Get info on our current letter. letter, (xshift, yshift, final_w, final_h) = get_letter(TEXT_CLT, char) painter.drawImage(QRect(x + TEXT_X_OFFSET + xshift, y + TEXT_Y_OFFSET + yshift, final_w, final_h), letter, letter.rect()) else: painter.drawImage(QRect(x, y, QUESTION.width(), QUESTION.height()), QUESTION, QUESTION.rect()) x += BOX_X_OFFSET x = BOX_LEFT y += BOX_Y_OFFSET painter.end() return out
def toImage( self ): t = time.time() tWAIT = time.time() self._arrayreq.wait() tWAIT = 1000.0*(time.time()-tWAIT) tAR = time.time() a = self._arrayreq.getResult() tAR = 1000.0*(time.time()-tAR) assert a.ndim == 2, "GrayscaleImageRequest.toImage(): result has shape %r, which is not 2-D" % (a.shape,) normalize = self._normalize if not normalize: normalize = [0,255] # FIXME: It is obviously wrong to truncate like this (right?) if a.dtype == np.uint64 or a.dtype == np.int64: warnings.warn("Truncating 64-bit pixels for display") if a.dtype == np.uint64: a = a.astype( np.uint32 ) elif a.dtype == np.int64: a = a.astype( np.int32 ) # # new conversion # tImg = None if _has_vigra and hasattr(vigra.colors, 'gray2qimage_ARGB32Premultiplied'): if self._normalize is None or \ self._normalize[0] >= self._normalize[1] or \ self._normalize == [0, 0]: #FIXME: fix volumina conventions n = np.asarray([0, 255], dtype=a.dtype) else: n = np.asarray(self._normalize, dtype=a.dtype) tImg = time.time() img = QImage(a.shape[1], a.shape[0], QImage.Format_ARGB32_Premultiplied) if not a.flags['C_CONTIGUOUS']: a = a.copy() vigra.colors.gray2qimage_ARGB32Premultiplied(a, byte_view(img), n) tImg = 1000.0*(time.time()-tImg) else: self.logger.warning("using slow image creation function") tImg = time.time() if self._normalize: #clipping has been implemented in this commit, #but it is not yet available in the packages obtained via easy_install #http://www.informatik.uni-hamburg.de/~meine/hg/qimage2ndarray/diff/fcddc70a6dea/qimage2ndarray/__init__.py a = np.clip(a, *self._normalize) img = gray2qimage(a, self._normalize) ret = img.convertToFormat(QImage.Format_ARGB32_Premultiplied) tImg = 1000.0*(time.time()-tImg) if self.logger.getEffectiveLevel() >= logging.DEBUG: tTOT = 1000.0*(time.time()-t) self.logger.debug("toImage (%dx%d, normalize=%r) took %f msec. (array req: %f, wait: %f, img: %f)" % (img.width(), img.height(), normalize, tTOT, tAR, tWAIT, tImg)) return img
def toImage( self ): t = time.time() tWAIT = time.time() self._arrayreq.wait() tWAIT = 1000.0*(time.time()-tWAIT) tAR = time.time() a = self._arrayreq.getResult() tAR = 1000.0*(time.time()-tAR) assert a.ndim == 2, "GrayscaleImageRequest.toImage(): result has shape %r, which is not 2-D" % (a.shape,) normalize = self._normalize if not normalize: normalize = [0,255] # FIXME: It is obviously wrong to truncate like this (right?) if a.dtype == np.uint64 or a.dtype == np.int64: warnings.warn("Truncating 64-bit pixels for display") if a.dtype == np.uint64: a = a.astype( np.uint32 ) elif a.dtype == np.int64: a = a.astype( np.int32 ) # # new conversion # tImg = None if _has_vigra and hasattr(vigra.colors, 'gray2qimage_ARGB32Premultiplied'): if self._normalize is None or \ self._normalize[0] >= self._normalize[1] or \ self._normalize == [0, 0]: #FIXME: fix volumina conventions n = np.asarray([0, 255], dtype=a.dtype) else: n = np.asarray(self._normalize, dtype=a.dtype) tImg = time.time() img = QImage(a.shape[1], a.shape[0], QImage.Format_ARGB32_Premultiplied) vigra.colors.gray2qimage_ARGB32Premultiplied(a, byte_view(img), n) tImg = 1000.0*(time.time()-tImg) else: self.logger.warning("using slow image creation function") tImg = time.time() if self._normalize: #clipping has been implemented in this commit, #but it is not yet available in the packages obtained via easy_install #http://www.informatik.uni-hamburg.de/~meine/hg/qimage2ndarray/diff/fcddc70a6dea/qimage2ndarray/__init__.py a = np.clip(a, *self._normalize) img = gray2qimage(a, self._normalize) ret = img.convertToFormat(QImage.Format_ARGB32_Premultiplied) tImg = 1000.0*(time.time()-tImg) if self.logger.getEffectiveLevel() >= logging.DEBUG: tTOT = 1000.0*(time.time()-t) self.logger.debug("toImage (%dx%d, normalize=%r) took %f msec. (array req: %f, wait: %f, img: %f)" % (img.width(), img.height(), normalize, tTOT, tAR, tWAIT, tImg)) return img
def updateROIcanvas(self, wormCanvas, worm_index_roi, comboBox_ROI, isDrawSkel): if not isinstance(self.frame_data, pd.DataFrame): #no trajectories data presented, nothing to do here wormCanvas.clear() return #update valid index for the comboBox comboBox_ROI.clear() comboBox_ROI.addItem(str(worm_index_roi)) #add the indexes of the current frame into the roi combo box for ind in self.frame_data[self.worm_index_type].data: comboBox_ROI.addItem(str(ind)) #extract individual worm ROI good = self.frame_data[self.worm_index_type] == worm_index_roi row_data = self.frame_data.loc[good].squeeze() if row_data.size == 0 or np.isnan(row_data['coord_x']) or np.isnan( row_data['coord_y']): #invalid data nothing to do here wormCanvas.clear() return worm_img, roi_corner = getWormROI(self.frame_img, row_data['coord_x'], row_data['coord_y'], row_data['roi_size']) #roi_corner = roi_corner+1 roi_ori_size = worm_img.shape worm_img = np.ascontiguousarray(worm_img) worm_qimg = QImage(worm_img.data, worm_img.shape[1], worm_img.shape[0], worm_img.strides[0], QImage.Format_Indexed8) worm_qimg = worm_qimg.convertToFormat(QImage.Format_RGB32, Qt.AutoColor) canvas_size = min(wormCanvas.height(), wormCanvas.width()) worm_qimg = worm_qimg.scaled(canvas_size, canvas_size, Qt.KeepAspectRatio) if isDrawSkel: if row_data['has_skeleton'] == 1: self.drawSkel(worm_img, worm_qimg, row_data, roi_corner=roi_corner) elif row_data['has_skeleton'] == 0: self.drawThreshMask(worm_img, worm_qimg, row_data, read_center=False) pixmap = QPixmap.fromImage(worm_qimg) wormCanvas.setPixmap(pixmap)
def readImage(self, filename, sbimage): image = QImage() if (image.load(filename.getString())): # Keep in 8-bits mode if that was what we read if (image.depth() == 8 and image.isGrayscale()): c = 1 else: # FIXME: consider if we should detect allGrayscale() and alpha (c = 2) c = 3 if image.hasAlphaChannel(): c = 4 image.convertToFormat(QImage.Format_ARGB32) else: image.convertToFormat(QImage.Format_RGB32) # FIXME 20080508 jkg: implement when pivy is ready #sbimage.setValue(SbVec2s(image.width(), image.height()), c, None) return True return False
def get_grayscale(data, w, h, crop=True): table = [] for i in range(256): table.append((255 << 24) | (i << 16) | (i << 8) | i) image = QImage(data, w, h, QImage.Format_Indexed8) image.setColorTable(table) image = image.convertToFormat(QImage.Format_ARGB32) if crop: image = image.copy(0, 0, w - 2, h - 2) return image
def get_trial(scene_info, show_bg=True, show_sprite=True, show_box=True): case_num = scene_info.chapter sprite_id = scene_info.sprite if case_num > 6 or case_num <= 0: case_num = 1 out = None if show_bg: if scene_info.movie >= 0: out = get_movie(scene_info.movie) elif scene_info.flash >= 0: out = get_flash(scene_info.flash) elif scene_info.bgd >= 0: out = get_bgd(scene_info.bgd) else: # out = QImage(os.path.join(BG_DIR, "bg_%03d.png" % (199 + case_num))) out = get_bg(199 + case_num) else: out = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) out.fill(QColor(0, 0, 0, 0).rgba()) if not out.format() is QImage.Format_ARGB32_Premultiplied: out = out.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(out) painter.setRenderHint(QPainter.Antialiasing, True) if show_sprite: sprite_id.sprite_type = SPRITE_TYPE.stand sprite = get_sprite(sprite_id) if sprite: painter.drawImage(out.rect(), sprite, sprite.rect()) if not scene_info.img_filter == IMG_FILTERS.unfiltered: painter.end() out = filter_image(out, scene_info.img_filter) painter = QPainter(out) painter.setRenderHint(QPainter.Antialiasing, True) if show_box: box = get_box(scene_info) painter.drawImage(out.rect(), box, box.rect()) return out
def get_trial(scene_info, show_bg = True, show_sprite = True, show_box = True): case_num = scene_info.chapter sprite_id = scene_info.sprite if case_num > 6 or case_num <= 0: case_num = 1 out = None if show_bg: if scene_info.movie >= 0: out = get_movie(scene_info.movie) elif scene_info.flash >= 0: out = get_flash(scene_info.flash) elif scene_info.bgd >= 0: out = get_bgd(scene_info.bgd) else: # out = QImage(os.path.join(BG_DIR, "bg_%03d.png" % (199 + case_num))) out = get_bg(199 + case_num) else: out = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) out.fill(QColor(0, 0, 0, 0).rgba()) if not out.format() is QImage.Format_ARGB32_Premultiplied: out = out.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(out) painter.setRenderHint(QPainter.Antialiasing, True) if show_sprite: sprite_id.sprite_type = SPRITE_TYPE.stand sprite = get_sprite(sprite_id) if sprite: painter.drawImage(out.rect(), sprite, sprite.rect()) if not scene_info.img_filter == IMG_FILTERS.unfiltered: painter.end() out = filter_image(out, scene_info.img_filter) painter = QPainter(out) painter.setRenderHint(QPainter.Antialiasing, True) if show_box: box = get_box(scene_info) painter.drawImage(out.rect(), box, box.rect()) return out
def get_flash(flash_id): if flash_id == -1: return None flash_file = os.path.join(FLASH_DIR, "fla_%03d.png" % flash_id) if not os.path.isfile(flash_file): flash_file = os.path.join(FLASH_DIR, "fla_%03d.png" % 999) out = QImage(flash_file) if not out.format == QImage.Format_ARGB32_Premultiplied: out = out.convertToFormat(QImage.Format_ARGB32_Premultiplied) return out
def get_bgd(bgd_id): if bgd_id == -1: return None bgd_file = os.path.join(BGD_DIR, "bgd_%03d.png" % bgd_id) if not os.path.isfile(bgd_file): bgd_file = os.path.join(BG_DIR, "%04d.png" % 9999) out = QImage(bgd_file) if not out.format == QImage.Format_ARGB32_Premultiplied: out = out.convertToFormat(QImage.Format_ARGB32_Premultiplied) return out
def get_movie(movie_id): if movie_id == -1: return None movie_file = os.path.join(MOVIE_DIR, "movie_%02d.png" % movie_id) if not os.path.isfile(movie_file): movie_file = os.path.join(MOVIE_DIR, "movie_%02d.png" % 99) out = QImage(movie_file) if not out.format == QImage.Format_ARGB32_Premultiplied: out = out.convertToFormat(QImage.Format_ARGB32_Premultiplied) return out
def font_bmp_to_alpha(filename): image = QImage(filename) image = image.convertToFormat(QImage.Format_ARGB32_Premultiplied) # Because the game uses 8bit grayscale bitmaps for its fonts with white as # fully visible and black as fully transparent, I'm using a naive technique # that averages the RGB value of a pixel and sets that as its alpha value. # I'm sure this will do fun stuff to other images, but it does the job # for the game's fonts, and that's all that really matters. ヽ(´ー`)ノ for i in range(image.width()): for j in range(image.height()): color = QColor(image.pixel(i, j)) alpha = (color.red() + color.green() + color.blue()) / 3 color.setAlpha(alpha) image.setPixel(i, j, color.rgba()) return image
def toImage( self ): t = time.time() tWAIT = time.time() self._arrayreq.wait() tWAIT = 1000.0*(time.time()-tWAIT) tAR = time.time() a = self._arrayreq.getResult() tAR = 1000.0*(time.time()-tAR) has_no_mask = not np.ma.is_masked(a) tImg = None if has_no_mask and _has_vigra and hasattr(vigra.colors, 'gray2qimage_ARGB32Premultiplied'): if not a.flags.contiguous: a = a.copy() tImg = time.time() img = QImage(a.shape[1], a.shape[0], QImage.Format_ARGB32_Premultiplied) tintColor = np.asarray([self._tintColor.redF(), self._tintColor.greenF(), self._tintColor.blueF()], dtype=np.float32); normalize = np.asarray(self._normalize, dtype=np.float32) if normalize[0] > normalize[1]: normalize = np.array( (0.0, 255.0) ).astype( np.float32 ) vigra.colors.alphamodulated2qimage_ARGB32Premultiplied(a, byte_view(img), tintColor, normalize) tImg = 1000.0*(time.time()-tImg) else: if has_no_mask: self.logger.warning("using unoptimized conversion functions") tImg = time.time() d = a[..., None].repeat(4, axis=-1) d[:,:,0] = d[:,:,0]*self._tintColor.redF() d[:,:,1] = d[:,:,1]*self._tintColor.greenF() d[:,:,2] = d[:,:,2]*self._tintColor.blueF() normalize = self._normalize img = array2qimage(d, normalize) img = img.convertToFormat(QImage.Format_ARGB32_Premultiplied) tImg = 1000.0*(time.time()-tImg) if self.logger.isEnabledFor(logging.DEBUG): tTOT = 1000.0*(time.time()-t) self.logger.debug("toImage (%dx%d, normalize=%r) took %f msec. (array req: %f, wait: %f, img: %f)" % (img.width(), img.height(), normalize, tTOT, tAR, tWAIT, tImg)) return img
def toImage( self ): t = time.time() tWAIT = time.time() self._arrayreq.wait() tWAIT = 1000.0*(time.time()-tWAIT) tAR = time.time() a = self._arrayreq.getResult() tAR = 1000.0*(time.time()-tAR) has_no_mask = not np.ma.is_masked(a) tImg = None if has_no_mask and _has_vigra and hasattr(vigra.colors, 'gray2qimage_ARGB32Premultiplied'): if not a.flags.contiguous: a = a.copy() tImg = time.time() img = QImage(a.shape[1], a.shape[0], QImage.Format_ARGB32_Premultiplied) tintColor = np.asarray([self._tintColor.redF(), self._tintColor.greenF(), self._tintColor.blueF()], dtype=np.float32); normalize = np.asarray(self._normalize, dtype=a.dtype) if normalize[0] > normalize[1]: normalize = None vigra.colors.alphamodulated2qimage_ARGB32Premultiplied(a, byte_view(img), tintColor, normalize) tImg = 1000.0*(time.time()-tImg) else: if has_no_mask: self.logger.warning("using unoptimized conversion functions") tImg = time.time() d = a[..., None].repeat(4, axis=-1) d[:,:,0] *= self._tintColor.redF() d[:,:,1] *= self._tintColor.greenF() d[:,:,2] *= self._tintColor.blueF() normalize = self._normalize img = array2qimage(d, normalize) img = img.convertToFormat(QImage.Format_ARGB32_Premultiplied) tImg = 1000.0*(time.time()-tImg) if self.logger.getEffectiveLevel() >= logging.DEBUG: tTOT = 1000.0*(time.time()-t) self.logger.debug("toImage (%dx%d, normalize=%r) took %f msec. (array req: %f, wait: %f, img: %f)" % (img.width(), img.height(), normalize, tTOT, tAR, tWAIT, tImg)) return img
def toImage( self ): t = time.time() tWAIT = time.time() self._arrayreq.wait() tWAIT = 1000.0*(time.time()-tWAIT) tAR = time.time() a = self._arrayreq.getResult() tAR = 1000.0*(time.time()-tAR) tImg = None if _has_vigra and hasattr(vigra.colors, 'gray2qimage_ARGB32Premultiplied'): if not a.flags.contiguous: a = a.copy() tImg = time.time() img = QImage(a.shape[1], a.shape[0], QImage.Format_ARGB32_Premultiplied) tintColor = np.asarray([self._tintColor.redF(), self._tintColor.greenF(), self._tintColor.blueF()], dtype=np.float32); normalize = np.asarray(self._normalize, dtype=a.dtype) if normalize[0] > normalize[1]: normalize = None vigra.colors.alphamodulated2qimage_ARGB32Premultiplied(a, byte_view(img), tintColor, normalize) tImg = 1000.0*(time.time()-tImg) else: self.logger.warning("using unoptimized conversion functions") tImg = time.time() shape = a.shape + (4,) d = np.empty(shape, dtype=np.float32) d[:,:,0] = a[:,:]*self._tintColor.redF() d[:,:,1] = a[:,:]*self._tintColor.greenF() d[:,:,2] = a[:,:]*self._tintColor.blueF() d[:,:,3] = a[:,:] normalize = self._normalize img = array2qimage(d, normalize) img = img.convertToFormat(QImage.Format_ARGB32_Premultiplied) tImg = 1000.0*(time.time()-tImg) if self.logger.getEffectiveLevel() >= logging.DEBUG: tTOT = 1000.0*(time.time()-t) self.logger.debug("toImage (%dx%d, normalize=%r) took %f msec. (array req: %f, wait: %f, img: %f)" % (img.width(), img.height(), normalize, tTOT, tAR, tWAIT, tImg)) return img return img
def updateROIcanvas(self, wormCanvas, worm_index_roi, comboBox_ROI, isDrawSkel): if not isinstance(self.frame_data, pd.DataFrame): #no trajectories data presented, nothing to do here wormCanvas.clear() return #update valid index for the comboBox comboBox_ROI.clear() comboBox_ROI.addItem(str(worm_index_roi)) #add the indexes of the current frame into the roi combo box for ind in self.frame_data[self.worm_index_type].data: comboBox_ROI.addItem(str(ind)) #extract individual worm ROI good = self.frame_data[self.worm_index_type] == worm_index_roi row_data = self.frame_data.loc[good].squeeze() if row_data.size == 0 or np.isnan(row_data['coord_x']) or np.isnan(row_data['coord_y']): #invalid data nothing to do here wormCanvas.clear() return worm_img, roi_corner = getWormROI(self.frame_img, row_data['coord_x'], row_data['coord_y'], row_data['roi_size']) #roi_corner = roi_corner+1 roi_ori_size = worm_img.shape worm_img = np.ascontiguousarray(worm_img) worm_qimg = QImage(worm_img.data, worm_img.shape[1], worm_img.shape[0], worm_img.strides[0], QImage.Format_Indexed8) worm_qimg = worm_qimg.convertToFormat(QImage.Format_RGB32, Qt.AutoColor) canvas_size = min(wormCanvas.height(),wormCanvas.width()) worm_qimg = worm_qimg.scaled(canvas_size,canvas_size, Qt.KeepAspectRatio) if isDrawSkel: if row_data['has_skeleton'] == 1: self.drawSkel(worm_img, worm_qimg, row_data, roi_corner = roi_corner) elif row_data['has_skeleton'] == 0: self.drawThreshMask(worm_img, worm_qimg, row_data, read_center=False) pixmap = QPixmap.fromImage(worm_qimg) wormCanvas.setPixmap(pixmap);
def __init__(self, image_file=None, default_wh=[1024.0, 1024.0], progress_handler = None): self.clear() self.image = None if progress_handler: self.ph = progress_handler else: self.ph = lambda i: None self.ph._message = '' self.ph._maxval = 0 if image_file and os.path.exists(image_file): # image tracing shall consist of 256 index colors ranked by luma img = QImage(image_file) if not img.isGrayscale() and QMessageBox("Image is not in grayscale", "Convert RGB image to grayscale?", QMessageBox.Question, QMessageBox.Yes, QMessageBox.No, 0).exec_() == QMessageBox.Yes: self.ph._message = 'Converting image to grayscale' self.ph._maxval = img.height() for y in range(img.height()): for x in range(img.width()): lightness = qGray(img.pixel(x, y)) img.setPixel(x, y, (lightness<<16) + (lightness<<8) + lightness) self.ph(y) colortable = [QColor(i, i, i).rgb() for i in xrange(256)] self.image = img.convertToFormat(QImage.Format_Indexed8, colortable) w, h = float(self.image.width()), float(self.image.height()) self.dpi = img.dotsPerMeterX() / 1000.0 * 25.4 else: w, h = default_wh self.dpi = 96.0 self.wh = [w, h] self.x1, self.y1, self.x2, self.y2 = [i/max(w, h) for i in [-w, -h, w, h]] self.dx = self.x2 - self.x1 self.dy = self.y2 - self.y1 # Resolution field in SVG units per pixel self.scale = self.dx / w
def ObjDetect(self): eightbit = QImage.convertToFormat(self._image, QImage.Format_Indexed8) eightbit = qim.byte_view(eightbit) eightbit = cv2.medianBlur(eightbit, 19) thr = cv2.adaptiveThreshold(eightbit, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) #ret, thr = cv2.threshold(eightbit, 127, 255, cv2.THRESH_BINARY) cv2.imshow("NAO", thr) k = cv2.waitKey(100) & 0xff if k == 27: cv2.destroyAllWindows() sys.exit(app.exec_()) contours0, hierarchy = cv2.findContours(thr, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) print len(contours0) for cnt in contours0[0]: contours = cv2.approxPolyDP(cnt, cv2.arcLength(contours0, True), True) #contours = cv2.approxPolyDP(contours, .01 * cv2.arcLength(contours, True), True) self._array = cv2.drawContours(self._array, [cnt], 0, (255, 0, 0), 2) cv2.imshow("NAO", self._array) k = cv2.waitKey(100) & 0xff if k == 27: cv2.destroyAllWindows() sys.exit(app.exec_())
def drawThreshMask(self, worm_img, worm_qimg, row_data, read_center = True): min_mask_area = row_data['area']/2 c1, c2 = (row_data['coord_x'], row_data['coord_y']) if read_center else (-1, -1) worm_mask, _ , _ = getWormMask(worm_img, row_data['threshold'], strel_size = self.strel_size, \ roi_center_x = c1, roi_center_y = c2, min_mask_area = min_mask_area) #worm_mask = np.zeros_like(worm_mask) #cv2.drawContours(worm_mask, [worm_cnt.astype(np.int32)], 0, 1, -1) worm_mask = QImage(worm_mask.data, worm_mask.shape[1], worm_mask.shape[0], worm_mask.strides[0], QImage.Format_Indexed8) worm_mask = worm_mask.convertToFormat(QImage.Format_RGB32, Qt.AutoColor) worm_mask = worm_mask.scaled(worm_qimg.width(),worm_qimg.height(), Qt.KeepAspectRatio) worm_mask = QPixmap.fromImage(worm_mask) worm_mask = worm_mask.createMaskFromColor(Qt.black) p = QPainter(worm_qimg) p.setPen(QColor(0,204,102)) p.drawPixmap(worm_qimg.rect(), worm_mask, worm_mask.rect()) p.end()
def draw_scene(scene_info, text=None): bg = None max_length = 0 kill_blanks = False if scene_info.mode in [ common.SCENE_MODES.normal, common.SCENE_MODES.normal_flat ]: bg = get_normal(scene_info) if scene_info.box_type == common.BOX_TYPES.flat: scene_info.mode = common.SCENE_MODES.normal_flat else: scene_info.mode = common.SCENE_MODES.normal elif scene_info.mode == common.SCENE_MODES.trial: bg = get_trial(scene_info) elif scene_info.mode == common.SCENE_MODES.novel: scene_info.box_type = common.BOX_TYPES.novel bg = get_normal(scene_info) elif scene_info.mode == common.SCENE_MODES.rules: bg = QImage(os.path.join(MENU_DIR, "rules.png")) elif scene_info.mode == common.SCENE_MODES.ammo: bg = QImage(os.path.join(MENU_DIR, "ammo-desc.png")) overlay = get_ammo(scene_info.file_id, 254, 117) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(bg) painter.setCompositionMode(QPainter.CompositionMode_DestinationOver) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() name = get_ammo_name(scene_info.file_id) if name: bg = print_text(bg, name, common.SCENE_MODES.ammoname, TEXT_FORMATS[common.SCENE_MODES.ammoname], False) elif scene_info.mode == common.SCENE_MODES.ammoname: bg = QImage(os.path.join(MENU_DIR, "ammo-list.png")) overlay = get_ammo(scene_info.file_id, 254, 61) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(bg) painter.setCompositionMode(QPainter.CompositionMode_DestinationOver) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() elif scene_info.mode == common.SCENE_MODES.present: bg = QImage(os.path.join(MENU_DIR, "present-desc.png")) overlay = get_present(scene_info.file_id, 248, 96) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(bg) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() name = get_present_name(scene_info.file_id) if name: bg = print_text(bg, name, common.SCENE_MODES.presentname, TEXT_FORMATS[common.SCENE_MODES.presentname], False) elif scene_info.mode == common.SCENE_MODES.presentname: bg = QImage(os.path.join(MENU_DIR, "present-list.png")) overlay = get_present(scene_info.file_id, 248, 46) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(bg) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() elif scene_info.mode == common.SCENE_MODES.menu: bg = QImage(os.path.join(MENU_DIR, "menu.png")) elif scene_info.mode == common.SCENE_MODES.report or scene_info.mode == common.SCENE_MODES.report2: bg = QImage(os.path.join(MENU_DIR, "report.png")) elif scene_info.mode == common.SCENE_MODES.skill or scene_info.mode == common.SCENE_MODES.skill2: bg = QImage(os.path.join(MENU_DIR, "skills.png")) elif scene_info.mode == common.SCENE_MODES.map: bg = QImage(os.path.join(MENU_DIR, "map.png")) elif scene_info.mode == common.SCENE_MODES.music: bg = QImage(os.path.join(MENU_DIR, "soundtest.png")) elif scene_info.mode in [ common.SCENE_MODES.eventname, common.SCENE_MODES.moviename, common.SCENE_MODES.artworkname ]: bg = QImage(os.path.join(MENU_DIR, "gallery.png")) if scene_info.mode == common.SCENE_MODES.eventname: overlay = get_event_icon(scene_info.file_id) elif scene_info.mode == common.SCENE_MODES.moviename: overlay = get_movie_icon(scene_info.file_id) elif scene_info.mode == common.SCENE_MODES.artworkname: overlay = get_artwork_icon(scene_info.file_id) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(bg) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() elif scene_info.mode == common.SCENE_MODES.theatre: bg = get_normal(scene_info) elif scene_info.mode == common.SCENE_MODES.debate or scene_info.mode == common.SCENE_MODES.hanron: bg = get_trial(scene_info, show_box=False) else: bg = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) bg.fill(QColor(0, 0, 0, 255).rgba()) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) if scene_info.cutin != -1: cutin = get_cutin(scene_info.cutin) painter = QPainter(bg) painter.drawImage(bg.rect(), cutin, cutin.rect()) painter.end() if scene_info.ammo != -1: ammo = get_ammo_ingame(scene_info.ammo) painter = QPainter(bg) painter.drawImage(bg.rect(), ammo, ammo.rect()) painter.end() if scene_info.present != -1: present = get_present_ingame(scene_info.present) painter = QPainter(bg) painter.drawImage(bg.rect(), present, present.rect()) painter.end() if scene_info.special == common.SCENE_SPECIAL.option: overlay = QImage(os.path.join(TEXTBOX_DIR, "option_bar.png")) painter = QPainter(bg) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() if not text == None and not text == "": bg = print_text(bg, text, common.SCENE_SPECIAL.option, TEXT_FORMATS[common.SCENE_SPECIAL.option], False) if not text == None and not text == "": bg = print_text(bg, text, scene_info.mode, TEXT_FORMATS[scene_info.mode]) return bg
def get_box(scene_info): mode = scene_info.mode box_color = scene_info.box_color box_type = scene_info.box_type speaking = scene_info.speaking speaker_id = scene_info.speaker headshot = scene_info.headshot chapter = scene_info.chapter if box_color != common.BOX_COLORS.orange and box_color != common.BOX_COLORS.green and box_color != common.BOX_COLORS.blue: box_color = common.BOX_COLORS.orange if not speaker_id in common.CHAR_IDS: speaker_id = None out = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) out.fill(QColor(0, 0, 0, 0).rgba()) painter = QPainter(out) painter.setRenderHint(QPainter.Antialiasing, True) # Some commonality between the boxes. box = QImage() button = QImage() if not speaker_id == None: nametag = QImage(os.path.join(NAMETAG_DIR, "%02d" % speaker_id)) else: nametag = QImage() nametag_offset = () if box_type == common.BOX_TYPES.flat: box = QImage(os.path.join(TEXTBOX_DIR, "box_gray.png")) button = QImage(os.path.join(TEXTBOX_DIR, "button_gray.png")) nametag_color = QColor(255, 255, 255, 255) nametag_offset = (9, 187) elif box_type == common.BOX_TYPES.normal: if mode == common.SCENE_MODES.normal: box = QImage(os.path.join(TEXTBOX_DIR, "box.png")) button = QImage(os.path.join(TEXTBOX_DIR, "button_%s.png" % box_color)) nametag_color = QColor(60, 60, 60, 255) nametag_offset = (10, 180) if not box.format() is QImage.Format_ARGB32_Premultiplied: box = box.convertToFormat(QImage.Format_ARGB32_Premultiplied) box_painter = QPainter(box) box_painter.setRenderHint(QPainter.Antialiasing, True) if speaking and not speaker_id == None: label_file = os.path.join(TEXTBOX_DIR, "speaking_label.png") speaking_file = os.path.join(TEXTBOX_DIR, "speaking_%s.png" % box_color) label = QImage(label_file) speaking_img = QImage(speaking_file) box_painter.drawImage(box.rect(), speaking_img, speaking_img.rect()) box_painter.drawImage(box.rect(), label, label.rect()) if speaker_id == 0: # Naegi gets a special text box. namebox = QImage(os.path.join(TEXTBOX_DIR, "name_naegi_%s.png" % box_color)) elif not speaker_id == None: namebox = QImage(os.path.join(TEXTBOX_DIR, "name_%s.png" % box_color)) else: namebox = QImage() box_painter.drawImage(box.rect(), namebox, namebox.rect()) box_painter.end() elif mode == common.SCENE_MODES.trial: if not headshot == None: box_base = QImage(os.path.join(TRIAL_DIR, "trial_speaking.png")) case_num = QImage(os.path.join(TRIAL_DIR, "case", "case%1d.png" % chapter)) underlay = QImage(os.path.join(TRIAL_DIR, "pink.png")) else: box_base = QImage(os.path.join(TRIAL_DIR, "trial_narration.png")) case_num = QImage() underlay = QImage() if not headshot == None: headshot = QImage(os.path.join(TRIAL_DIR, "headshot", "%02d.png" % headshot)) else: headshot = QImage() button = QImage(os.path.join(TRIAL_DIR, "button.png")) nametag_color = QColor(0, 0, 0, 255) nametag_offset = (20, 183) box = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) box.fill(QColor(0, 0, 0, 0).rgba()) box_painter = QPainter(box) box_painter.setRenderHint(QPainter.Antialiasing, True) box_painter.drawImage(box.rect(), underlay, underlay.rect()) box_painter.drawImage(box.rect(), headshot, headshot.rect()) box_painter.drawImage(box.rect(), box_base, box_base.rect()) box_painter.drawImage(box.rect(), case_num, case_num.rect()) box_painter.end() else: box = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) box.fill(QColor(0, 0, 0, 0).rgba()) painter.drawImage(out.rect(), box, box.rect()) painter.drawImage(out.rect(), button, button.rect()) if not speaker_id == None: nametag = replace_all_colors(nametag, nametag_color) painter.drawImage(QRect(nametag_offset[0], nametag_offset[1], nametag.width(), nametag.height()), nametag, nametag.rect()) painter.end() return out
def render(self, params): self.check_required_params(params) with change_directory(self.project_root): crs = QgsCoordinateReferenceSystem() crs.createFromSrid(params.get('srs')) img = QImage( QSize(*params.get('image_size')), QImage.Format_ARGB32_Premultiplied ) dpm = 1 / 0.00028 img.setDotsPerMeterX(dpm) img.setDotsPerMeterY(dpm) # set background color bgcolor = params.get('bgcolor') if params.get('transparent'): # fully transparent bgcolor.append(0) else: # fully opaque bgcolor.append(255) color = QColor(*bgcolor) img.fill(color) map_settings = QgsMapSettings() map_settings.setBackgroundColor(color) map_settings.setDestinationCrs(crs) map_settings.setCrsTransformEnabled(True) map_settings.setExtent(QgsRectangle(*params.get('bbox'))) map_settings.setOutputDpi(img.logicalDpiX()) map_settings.setOutputSize(img.size()) map_settings.setMapUnits(crs.mapUnits()) layers = params.get('layers') self.setTransparencies(layers, params.get('transparencies')) map_settings.setLayers(layers) p = QPainter() p.begin(img) job = QgsMapRendererCustomPainterJob(map_settings, p) job.start() job.waitForFinished() map_buffer = QBuffer() map_buffer.open(QIODevice.ReadWrite) if params.get('image_format') == 'jpeg': img.save(map_buffer, 'JPEG') elif params.get('image_format') == 'png8': png8 = img.convertToFormat(QImage.Format_Indexed8) png8.save(map_buffer, "PNG") else: img.save(map_buffer, 'PNG') # clean up p.end() map_buffer.close() return map_buffer.data()
def draw_scene(scene_info, text = None): bg = None max_length = 0 kill_blanks = False if scene_info.mode == common.SCENE_MODES.normal: bg = get_normal(scene_info) elif scene_info.mode == common.SCENE_MODES.trial: bg = get_trial(scene_info) elif scene_info.mode == common.SCENE_MODES.rules: bg = QImage(os.path.join(MENU_DIR, "rules.png")) elif scene_info.mode in [common.SCENE_MODES.ammo, common.SCENE_MODES.ammoname, common.SCENE_MODES.present, common.SCENE_MODES.presentname]: bg = QImage(os.path.join(MENU_DIR, "ammo.png")) if scene_info.mode in [common.SCENE_MODES.ammo, common.SCENE_MODES.ammoname]: overlay = get_ammo_menu(scene_info.file_id) else: overlay = get_present_icon(scene_info.file_id) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(bg) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() elif scene_info.mode == common.SCENE_MODES.menu: bg = QImage(os.path.join(MENU_DIR, "menu.png")) elif scene_info.mode == common.SCENE_MODES.report or scene_info.mode == common.SCENE_MODES.report2: bg = QImage(os.path.join(MENU_DIR, "report.png")) elif scene_info.mode == common.SCENE_MODES.skill or scene_info.mode == common.SCENE_MODES.skill2: bg = QImage(os.path.join(MENU_DIR, "skills.png")) elif scene_info.mode == common.SCENE_MODES.map: bg = QImage(os.path.join(MENU_DIR, "map.png")) elif scene_info.mode == common.SCENE_MODES.music: bg = QImage(os.path.join(MENU_DIR, "soundtest.png")) elif scene_info.mode == common.SCENE_MODES.eventname or scene_info.mode == common.SCENE_MODES.moviename: bg = QImage(os.path.join(MENU_DIR, "gallery.png")) if scene_info.mode == common.SCENE_MODES.eventname: overlay = get_event_icon(scene_info.file_id) else: overlay = get_movie_icon(scene_info.file_id) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(bg) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() elif scene_info.mode == common.SCENE_MODES.theatre: bg = get_normal(scene_info) elif scene_info.mode == common.SCENE_MODES.debate: bg = get_trial(scene_info, show_box = False) else: bg = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) bg.fill(QColor(0, 0, 0, 255).rgba()) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) if scene_info.cutin != -1: cutin = get_cutin(scene_info.cutin) painter = QPainter(bg) painter.drawImage(bg.rect(), cutin, cutin.rect()) painter.end() if scene_info.ammo != -1: ammo = get_ammo_ingame(scene_info.ammo) painter = QPainter(bg) painter.drawImage(bg.rect(), ammo, ammo.rect()) painter.end() if scene_info.special == common.SCENE_SPECIAL.option: overlay = QImage(os.path.join(TEXTBOX_DIR, "option_bar.png")) painter = QPainter(bg) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() if not text == None and not text == "": bg = print_text(bg, text, common.SCENE_SPECIAL.option, False) if not text == None and not text == "": bg = print_text(bg, text, scene_info.mode) return bg
def get_box(scene_info): mode = scene_info.mode box_color = scene_info.box_color box_type = scene_info.box_type speaking = scene_info.speaking speaker_id = scene_info.speaker headshot = scene_info.headshot chapter = scene_info.chapter if box_color != common.BOX_COLORS.yellow and box_color != common.BOX_COLORS.green and box_color != common.BOX_COLORS.blue: box_color = common.BOX_COLORS.yellow out = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) out.fill(QColor(0, 0, 0, 0).rgba()) painter = QPainter(out) painter.setRenderHint(QPainter.Antialiasing, True) # Some commonality between the boxes. box = QImage() button = QImage() nametag_x = 0 nametag_y = 0 nametag_color = QColor(255, 255, 255, 255) nametag_vert = False if box_type == common.BOX_TYPES.flat: box = QImage(os.path.join(TEXTBOX_DIR, "box_gray.png")) button = QImage(os.path.join(TEXTBOX_DIR, "button_%s.png" % box_color)) nametag_x = 10 nametag_y = 176 nametag_color = QColor(255, 255, 255, 255) nametag_vert = False elif box_type == common.BOX_TYPES.novel: box = QImage(os.path.join(TEXTBOX_DIR, "box_novel.png")) elif box_type == common.BOX_TYPES.normal: if mode == common.SCENE_MODES.normal: box = QImage(os.path.join(TEXTBOX_DIR, "box.png")) button = QImage( os.path.join(TEXTBOX_DIR, "button_%s.png" % box_color)) nametag_x = 0 nametag_y = 220 nametag_color = QColor(50, 50, 50, 255) nametag_vert = True if not box.format() is QImage.Format_ARGB32_Premultiplied: box = box.convertToFormat(QImage.Format_ARGB32_Premultiplied) box_painter = QPainter(box) box_painter.setRenderHint(QPainter.Antialiasing, True) if speaker_id == 0: # Main character gets a special text box. namebox = QImage( os.path.join(TEXTBOX_DIR, "name_%s_mc.png" % box_color)) else: namebox = QImage( os.path.join(TEXTBOX_DIR, "name_%s.png" % box_color)) box_painter.drawImage(box.rect(), namebox, namebox.rect()) box_painter.end() elif mode == common.SCENE_MODES.trial: box_base = QImage(os.path.join(TRIAL_DIR, "trial_box.png")) banner = QImage(os.path.join(TRIAL_DIR, "trial_banner.png")) if speaker_id == 0: # Main character gets a special text box. namebox = QImage(os.path.join(TRIAL_DIR, "trial_name_mc.png")) else: namebox = QImage(os.path.join(TRIAL_DIR, "trial_name.png")) if not headshot == None: case_num = QImage( os.path.join(TRIAL_DIR, "case_%02d.png" % chapter)) headshot = QImage( os.path.join(TRIAL_DIR, "headshot", "%02d.png" % headshot)) underlay = QImage(os.path.join(TRIAL_DIR, "trial_headshot.png")) else: case_num = QImage() underlay = QImage() headshot = QImage() button = QImage(os.path.join(TRIAL_DIR, "button.png")) nametag_x = 12 nametag_y = 168 nametag_color = QColor(255, 255, 255, 255) nametag_vert = False box = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) box.fill(QColor(0, 0, 0, 0).rgba()) box_painter = QPainter(box) box_painter.setRenderHint(QPainter.Antialiasing, True) box_painter.drawImage(box.rect(), banner, banner.rect()) box_painter.drawImage(box.rect(), namebox, namebox.rect()) box_painter.drawImage(box.rect(), box_base, box_base.rect()) box_painter.drawImage(box.rect(), underlay, underlay.rect()) box_painter.drawImage(box.rect(), headshot, headshot.rect()) box_painter.drawImage(box.rect(), case_num, case_num.rect()) box_painter.end() else: box = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) box.fill(QColor(0, 0, 0, 0).rgba()) painter.drawImage(out.rect(), box, box.rect()) painter.drawImage(out.rect(), button, button.rect()) if not speaker_id == None: nametag = get_nametag(speaker_id, nametag_x, nametag_y, nametag_color, nametag_vert) painter.drawImage(out.rect(), nametag, nametag.rect()) painter.end() return out
class HDF5videoViewer_GUI(QMainWindow): def __init__(self, ui = ''): super().__init__() # Set up the user interface from Designer. if not ui: self.ui = Ui_ImageViewer() else: self.ui = ui self.ui.setupUi(self) self.isPlay = False self.fid = -1 self.image_group = -1 self.videos_dir = '' #self.videos_dir = r"/Volumes/behavgenom$/GeckoVideo/Results/20150521_1115/" #self.videos_dir = os.path.expanduser("~") + os.sep + 'Downloads' + os.sep + 'wetransfer-cf3818' + os.sep #self.ui.imageCanvas.setFocusPolicy(Qt.ClickFocus) self.h5path = self.ui.comboBox_h5path.itemText(0) self.ui.pushButton_video.clicked.connect(self.getVideoFile) self.ui.playButton.clicked.connect(self.playVideo) self.ui.imageSlider.sliderPressed.connect(self.imSldPressed) self.ui.imageSlider.sliderReleased.connect(self.imSldReleased) self.ui.spinBox_frame.valueChanged.connect(self.updateFrameNumber) self.ui.doubleSpinBox_fps.valueChanged.connect(self.updateFPS) self.ui.spinBox_step.valueChanged.connect(self.updateFrameStep) self.ui.spinBox_step.valueChanged.connect(self.updateFrameStep) self.ui.comboBox_h5path.activated.connect(self.getImGroup) self.ui.pushButton_h5groups.clicked.connect(self.updateGroupNames) self.updateFPS() self.updateFrameStep() # SET UP RECURRING EVENTS self.timer = QTimer() self.timer.timeout.connect(self.getNextImage) #Scroller def imSldPressed(self): self.ui.imageSlider.setCursor(Qt.ClosedHandCursor) def imSldReleased(self): self.ui.imageSlider.setCursor(Qt.OpenHandCursor) if self.image_group != -1: self.frame_number = int(round((self.tot_frames-1)*self.ui.imageSlider.value()/100)) self.ui.spinBox_frame.setValue(self.frame_number) #self.updateImage() #frame spin box def updateFrameNumber(self): self.frame_number = self.ui.spinBox_frame.value() progress = round(100*self.frame_number/self.tot_frames) if progress != self.ui.imageSlider.value(): self.ui.imageSlider.setValue(progress) self.updateImage() #fps spin box def updateFPS(self): self.fps = self.ui.doubleSpinBox_fps.value() #frame steps spin box def updateFrameStep(self): self.frame_step = self.ui.spinBox_step.value() #Play Button def playVideo(self): if self.image_group == -1: return if not self.isPlay: self.startPlay() else: self.stopPlay() def startPlay(self): self.timer.start(round(1000/self.fps)) self.isPlay = True self.ui.playButton.setText('Stop') self.ui.doubleSpinBox_fps.setEnabled(False) def stopPlay(self): self.timer.stop() self.isPlay = False self.ui.playButton.setText('Play') self.ui.doubleSpinBox_fps.setEnabled(True) #Function to get the new valid frame during video play def getNextImage(self): self.frame_number += self.frame_step if self.frame_number >= self.tot_frames: self.frame_number = self.tot_frames-1 self.stopPlay() self.ui.spinBox_frame.setValue(self.frame_number) #update image: get the next frame_number, and resize it to fix in the GUI area def updateImage(self): if self.image_group == -1: return self.readImage() self.pixmap = QPixmap.fromImage(self.frame_qimg) self.ui.imageCanvas.setPixmap(self.pixmap); def readImage(self): self.label_height = self.ui.imageCanvas.height() self.label_width = self.ui.imageCanvas.width() self.frame_img = self.image_group[self.frame_number,:,:]; #equalize and cast if it is not uint8 if self.frame_img.dtype != np.uint8: top = np.max(self.frame_img) bot = np.min(self.frame_img) self.frame_img = (self.frame_img-bot)*255./(top-bot) self.frame_img = np.round(self.frame_img).astype(np.uint8) self.frame_qimg = QImage(self.frame_img.data, self.image_width, self.image_height, self.frame_img.strides[0], QImage.Format_Indexed8) self.frame_qimg = self.frame_qimg.convertToFormat(QImage.Format_RGB32, Qt.AutoColor) self.frame_qimg = self.frame_qimg.scaled(self.label_width, self.label_height, Qt.KeepAspectRatio) #file dialog to the the hdf5 file def getVideoFile(self): vfilename = QFileDialog.getOpenFileName(self, "Find HDF5 video file", self.videos_dir, "HDF5 files (*.hdf5);; All files (*)") if vfilename: if self.fid != -1: self.fid.close() self.ui.imageCanvas.clear() self.vfilename = vfilename self.updateVideoFile() def updateVideoFile(self): if not os.path.exists(self.vfilename): QMessageBox.critical(self, 'The hdf5 video file does not exists', "The hdf5 video file does not exists. Please select a valid file", QMessageBox.Ok) return self.ui.lineEdit_video.setText(self.vfilename) self.videos_dir = self.vfilename.rpartition(os.sep)[0] + os.sep self.fid = tables.File(self.vfilename, 'r') self.updateImGroup() def updateGroupNames(self): valid_groups = [] for group in self.fid.walk_groups("/"): for array in self.fid.list_nodes(group, classname='Array'): if array.ndim == 3: valid_groups.append(array._v_pathname) if not valid_groups: QMessageBox.critical(self, '', "No valid video groups were found. Dataset with three dimensions and uint8 data type.", QMessageBox.Ok) return self.ui.comboBox_h5path.clear() for kk in valid_groups: self.ui.comboBox_h5path.addItem(kk) self.getImGroup(0) self.updateImage() def getImGroup(self, index): self.h5path = self.ui.comboBox_h5path.itemText(index) self.updateImGroup() #read a valid groupset from the hdf5 def updateImGroup(self): if self.fid == -1: return #self.h5path = self.ui.comboBox_h5path.text() if not self.h5path in self.fid: self.ui.imageCanvas.clear() self.image_group == -1 QMessageBox.critical(self, 'The groupset path does not exists', "The groupset path does not exists. You must specify a valid groupset path", QMessageBox.Ok) return self.image_group = self.fid.get_node(self.h5path) if len(self.image_group.shape) != 3: self.ui.imageCanvas.clear() self.image_group == -1 QMessageBox.critical(self, 'Invalid groupset', "Invalid groupset. The groupset must have three dimensions", QMessageBox.Ok) self.tot_frames = self.image_group.shape[0] self.image_height = self.image_group.shape[1] self.image_width = self.image_group.shape[2] self.ui.spinBox_frame.setMaximum(self.tot_frames-1) self.frame_number = 0 self.ui.spinBox_frame.setValue(self.frame_number) self.updateImage() def setFileName(self, filename): self.filename = filename self.ui.lineEdit.setText(filename) def resizeEvent(self, event): if self.fid != -1: self.updateImage() def keyPressEvent(self, event): key = event.key() #Duplicate the frame step size (speed) when pressed > or .: if key == 46 or key == 62: self.frame_step *= 2 self.ui.spinBox_step.setValue(self.frame_step) #Half the frame step size (speed) when pressed: < or , elif key == 44 or key == 60: self.frame_step //=2 if self.frame_step<1: self.frame_step = 1 self.ui.spinBox_step.setValue(self.frame_step) #print(event.key()) elif self.fid == -1: return #Move backwards when are pressed elif key == Qt.Key_Left or key == 39: self.frame_number -= self.frame_step if self.frame_number<0: self.frame_number = 0 self.ui.spinBox_frame.setValue(self.frame_number) #Move forward when are pressed elif key == Qt.Key_Right or key == 92: self.frame_number += self.frame_step if self.frame_number >= self.tot_frames: self.frame_number = self.tot_frames-1 self.ui.spinBox_frame.setValue(self.frame_number) else: QMainWindow.keyPressEvent(self, event)
def _updateImage(self): self._alImage = self._videoProxy.getImageRemote(self._imgClient) self._image = QImage(self._alImage[6], self._alImage[0], self._alImage[1], QImage.Format_RGB888) #there may be a way to avoid using QImage but idk yet self._image = QImage.convertToFormat(self._image, QImage.Format_RGB32) self.convertToCV()
def draw_scene(scene_info, text = None): bg = None max_length = 0 kill_blanks = False if scene_info.mode in [common.SCENE_MODES.normal, common.SCENE_MODES.normal_flat]: bg = get_normal(scene_info) if scene_info.box_type == common.BOX_TYPES.flat: scene_info.mode = common.SCENE_MODES.normal_flat else: scene_info.mode = common.SCENE_MODES.normal elif scene_info.mode == common.SCENE_MODES.trial: bg = get_trial(scene_info) elif scene_info.mode == common.SCENE_MODES.novel: scene_info.box_type = common.BOX_TYPES.novel bg = get_normal(scene_info) elif scene_info.mode == common.SCENE_MODES.rules: bg = QImage(os.path.join(MENU_DIR, "rules.png")) elif scene_info.mode == common.SCENE_MODES.ammo: bg = QImage(os.path.join(MENU_DIR, "ammo-desc.png")) overlay = get_ammo(scene_info.file_id, 254, 117) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(bg) painter.setCompositionMode(QPainter.CompositionMode_DestinationOver) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() name = get_ammo_name(scene_info.file_id) if name: bg = print_text(bg, name, common.SCENE_MODES.ammoname, TEXT_FORMATS[common.SCENE_MODES.ammoname], False) elif scene_info.mode == common.SCENE_MODES.ammoname: bg = QImage(os.path.join(MENU_DIR, "ammo-list.png")) overlay = get_ammo(scene_info.file_id, 254, 61) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(bg) painter.setCompositionMode(QPainter.CompositionMode_DestinationOver) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() elif scene_info.mode == common.SCENE_MODES.present: bg = QImage(os.path.join(MENU_DIR, "present-desc.png")) overlay = get_present(scene_info.file_id, 248, 96) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(bg) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() name = get_present_name(scene_info.file_id) if name: bg = print_text(bg, name, common.SCENE_MODES.presentname, TEXT_FORMATS[common.SCENE_MODES.presentname], False) elif scene_info.mode == common.SCENE_MODES.presentname: bg = QImage(os.path.join(MENU_DIR, "present-list.png")) overlay = get_present(scene_info.file_id, 248, 46) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(bg) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() elif scene_info.mode == common.SCENE_MODES.menu: bg = QImage(os.path.join(MENU_DIR, "menu.png")) elif scene_info.mode == common.SCENE_MODES.report or scene_info.mode == common.SCENE_MODES.report2: bg = QImage(os.path.join(MENU_DIR, "report.png")) elif scene_info.mode == common.SCENE_MODES.skill or scene_info.mode == common.SCENE_MODES.skill2: bg = QImage(os.path.join(MENU_DIR, "skills.png")) elif scene_info.mode == common.SCENE_MODES.map: bg = QImage(os.path.join(MENU_DIR, "map.png")) elif scene_info.mode == common.SCENE_MODES.music: bg = QImage(os.path.join(MENU_DIR, "soundtest.png")) elif scene_info.mode in [common.SCENE_MODES.eventname, common.SCENE_MODES.moviename, common.SCENE_MODES.artworkname]: bg = QImage(os.path.join(MENU_DIR, "gallery.png")) if scene_info.mode == common.SCENE_MODES.eventname: overlay = get_event_icon(scene_info.file_id) elif scene_info.mode == common.SCENE_MODES.moviename: overlay = get_movie_icon(scene_info.file_id) elif scene_info.mode == common.SCENE_MODES.artworkname: overlay = get_artwork_icon(scene_info.file_id) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) painter = QPainter(bg) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() elif scene_info.mode == common.SCENE_MODES.theatre: bg = get_normal(scene_info) elif scene_info.mode == common.SCENE_MODES.debate or scene_info.mode == common.SCENE_MODES.hanron: bg = get_trial(scene_info, show_box = False) else: bg = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) bg.fill(QColor(0, 0, 0, 255).rgba()) if not bg.format() is QImage.Format_ARGB32_Premultiplied: bg = bg.convertToFormat(QImage.Format_ARGB32_Premultiplied) if scene_info.cutin != -1: cutin = get_cutin(scene_info.cutin) painter = QPainter(bg) painter.drawImage(bg.rect(), cutin, cutin.rect()) painter.end() if scene_info.ammo != -1: ammo = get_ammo_ingame(scene_info.ammo) painter = QPainter(bg) painter.drawImage(bg.rect(), ammo, ammo.rect()) painter.end() if scene_info.present != -1: present = get_present_ingame(scene_info.present) painter = QPainter(bg) painter.drawImage(bg.rect(), present, present.rect()) painter.end() if scene_info.special == common.SCENE_SPECIAL.option: overlay = QImage(os.path.join(TEXTBOX_DIR, "option_bar.png")) painter = QPainter(bg) painter.drawImage(bg.rect(), overlay, overlay.rect()) painter.end() if not text == None and not text == "": bg = print_text(bg, text, common.SCENE_SPECIAL.option, TEXT_FORMATS[common.SCENE_SPECIAL.option], False) if not text == None and not text == "": bg = print_text(bg, text, scene_info.mode, TEXT_FORMATS[scene_info.mode]) return bg
class pngDisplay(QWidget): def __init__(self, parent=None): super(pngDisplay, self).__init__(parent) #self.profiler = cProfile.Profile() # create the label that displays the image - cribbing from the Image # Viewer example in the Qt docs. self.imLabel = QLabel() self.imLabel.setBackgroundRole(QPalette.Base) self.imLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.imLabel.setScaledContents(True) # Create a gray field to use when no png is available self.defaultPM = QPixmap(700,900) self.defaultPM.fill(QColor("gray")) # Create a scroll area within which to display our imLabel, this # enables the creation of horizontal and vertical scroll bars, when # the imLabel exceeds the size of the scroll area. self.scarea = QScrollArea() # The following two lines make sure that page up/dn gets through # the scrollarea widget and up to us. self.setFocusPolicy(Qt.ClickFocus) self.scarea.setFocusProxy(self) self.scarea.setBackgroundRole(QPalette.Dark) #self.scarea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) #self.scarea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.scarea.setWidget(self.imLabel) # create the text label that will have the page number in it self.txLabel = QLabel(u"No image") self.txLabel.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) self.txLabel.setFrameStyle(QFrame.Sunken | QFrame.StyledPanel) # Create a spinbox to set the zoom from 15 to 200 with a label: # (originally a slider, hence the name) self.minZoom = 0.15 self.maxZoom = 2.00 self.zlider = QSpinBox() self.zlider.setRange(int(100*self.minZoom),int(100*self.maxZoom)) # connect the value change signal to a slot to handle it self.connect(self.zlider, SIGNAL("valueChanged(int)"), self.newZoomFactor) # create the to-width and to-height zoom buttons zoomWidthButton = QPushButton(u'to Width') self.connect(zoomWidthButton, SIGNAL("clicked()"), self.zoomToWidth) zoomHeightButton = QPushButton(u'to Height') self.connect(zoomHeightButton, SIGNAL("clicked()"), self.zoomToHeight) # Make an hbox to contain the spinbox and two pushbuttons, with # stretch on left and right to center the group. zlabel = QLabel( u'&Zoom ' + str(self.zlider.minimum()) + '-' + str(self.zlider.maximum()) + '%') zlabel.setBuddy(self.zlider) zhbox = QHBoxLayout() zhbox.addStretch(1) zhbox.addWidget(zlabel,0,Qt.AlignLeft) zhbox.addWidget(self.zlider,0) zhbox.addStretch(1) zhbox.addWidget(zoomWidthButton) zhbox.addWidget(zoomHeightButton) zhbox.addStretch(1) # With all the pieces in hand, create our layout basically a # vertical stack: scroll area, label, slider box. vbox = QVBoxLayout() # the image gets a high stretch and default alignment, the text # label hugs the bottom and doesn't stretch at all. vbox.addWidget(self.txLabel,0,Qt.AlignBottom) vbox.addWidget(self.scarea,10) vbox.addLayout(zhbox,0) self.setLayout(vbox) # Initialize assuming no book is open. self.ready = False # nothing to display # Recover the last-set zoom factor from the settings object, default 1.0 qv = IMC.settings.value("pngs/zoomFactor",QVariant(1.0)) self.zoomFactor = qv.toFloat()[0] # The following causes entry into newZoomFactor, below, which tests # self.ready, hence the latter has to be assigned-to first. self.zlider.setValue(int(self.zoomFactor*100)) self.clear() # local subroutine to initialize our contents for an empty edit. # called from _init_ and from newPosition when we discover the file # has been cleared on us. Don't reset the zoomFactor, leave it as # the user last set it. def clear(self): # Clear the page name, used by pqNotes IMC.currentImageNumber = None # will be name of last png file e.g. "002" # Clear the page filename, used in our caption label self.lastPage = QString() # last file name e.g. "002.png" # Clear the path to the pngs folder, used to fetch image files self.pngPath = QString() # Clear the index of the last-shown page in the page table # -1 means no page is being displayed. self.lastIndex = -1 # Clear the index of the next page to display, normally same as last self.nextIndex = -1 # Set not-ready to indicate no pngs directory available. self.ready = False # Clear out & release storage of our QImage and QPixmaps self.pixmap = QPixmap() # null pixmap self.image = QImage() self.noImage() # show gray image # Display a blank gray frame and "No Image" below. # Called from clear() above and from showPage when no valid image. def noImage(self) : self.imLabel.setPixmap(self.defaultPM) self.txLabel.setText(u"No image") self.lastIndex = -1 # didn't see a prior page self.nextIndex = -1 # This slot gets the main window's signal shuttingDown. # We save our current zoom factor into IMC.settings. def shuttingDown(self): IMC.settings.setValue("pngs/zoomFactor",QVariant(self.zoomFactor)) # This slot gets pqMain's signal docHasChanged(QString), telling # us that a different document has been loaded. This could be for # a successful File>Open, or a failed File>Open or File>New. # The bookPath is a null QString for File>New, or the full bookPath. # If the latter, we convert that into the path to the pngs folder, # and see if bookPath/pngs is a directory. If so, we set self.ready # to true, indicating it is worthwhile to try opening image files. # At this point the gray image is displayed and previously would remain displayed # until the user moved the cursor in some way, generating cursorPositionChanged. # That's a minor annoyance, to avoid it we will fake that signal now. def newFile(self, bookPath): if not bookPath.isNull(): # this was successful File>Open finf = QFileInfo(bookPath) self.pngPath = finf.absolutePath().append(u"/pngs/") finf = QFileInfo(self.pngPath) if finf.exists() and finf.isDir(): # looking good self.ready = True self.newPosition() else: # We could inform the user we couldn't find a pngs folder, # but you know -- the user is probably already aware of that. self.clear() # just put up the gray default image else: # It was a File>New self.clear() # This function is the slot that is connected to the editor's # cursorPositionChanged signal. Its input is cursor position and # the page table. Its output is to set self.nextIndex to the # desired next image table row, and to call showPage. def newPosition(self): if self.ready : # We have a book and some pngs. Find the position of the higher end # of the current selection. pos = IMC.editWidget.textCursor().selectionEnd() # Get the page table index that matches this position, or -1 # if that is above the first psep, or there is no page data self.nextIndex = IMC.pageTable.getIndex(pos) else :# No file loaded or no pngs folder found. self.nextIndex = -1 if self.nextIndex != self.lastIndex : self.showPage() # Display the page indexed by self.nextIndex. This is called when the cursor # moves to a new page (newPosition, above), or when the PageUp/Dn keys are used, # (keyPressEvent, below) or when the zoom factor changes in any of several ways. def showPage(self): # If self.lastIndex is different from self.nextIndex, the page has # changed, and we need to load a new image. if self.lastIndex != self.nextIndex : self.lastIndex = self.nextIndex # don't come here again until it changes. if self.lastIndex > -1 : # Form the image filename as a Qstring, e.g. "025" and save that for # use by pqNotes: IMC.currentImageNumber = IMC.pageTable.getScan(self.lastIndex) # dbg = unicode(IMC.currentImageNumber) # Form the complete filename by appending ".png" and save as # self.lastPage for use in forming our caption label. self.lastPage = QString(IMC.currentImageNumber).append(QString(u".png")) # dbg = unicode(self.lastPage) # Form the full path to the image. Try to load it as a QImage. pngName = QString(self.pngPath).append(self.lastPage) self.image = QImage(pngName,'PNG') # dbg = unicode(self.image) # dbg = self.image.isNull() # If that successfully loaded an image, make sure it is one byte/pixel. if not self.image.isNull() \ and self.image.format() != QImage.Format_Indexed8 : # It might be Format_Mono (1 bit/pixel) or even Format_RGB32. self.image = self.image.convertToFormat(QImage.Format_Indexed8,Qt.ColorOnly) # Convert the image to a pixmap. If it's null, so is the pixmap. self.pixmap = QPixmap.fromImage(self.image,Qt.ColorOnly) else : IMC.currentImageNumber = QString(u"n.a.") self.lastPage = QString() self.image = QImage() self.pixmap = QPixmap() if not self.pixmap.isNull(): # We successfully found and loaded an image and converted it to pixmap. # Load it in our label for display, set the zoom factor, and the caption. # We do this every time through (even if lastIndex equalled nextIndex) # because the zoomfactor might have changed. self.imLabel.setPixmap(self.pixmap) self.imLabel.resize( self.zoomFactor * self.pixmap.size() ) folio = IMC.pageTable.getDisplay(self.lastIndex) self.txLabel.setText(u"image {0} (folio {1})".format(self.lastPage,folio)) else: # no file was loaded. It's ok if pages are missing self.noImage() # display the gray image. # Catch the signal from the Zoom spinbox with a new value. # Store the new value as a float, and if we have a page, repaint it. def newZoomFactor(self,new_value): self.zoomFactor = new_value / 100 if self.ready : self.showPage() # Catch the click on zoom-to-width and zoom-to height. The job is basically # the same for both. 1: Using the QImage that should be in self.image, # scan the pixels to find the width (height) of the nonwhite area. # 2. Get the ratio of that to our image label's viewport width (height). # 4. Set that ratio as the zoom factor and redraw the image. And finally # 5. Set the scroll position(s) of our scroll area to left-justify the text. # # We get access to the pixels using QImage:bits() which gives us a PyQt4 # "voidptr" that we can index to get byte values. # def zoomToWidth(self): if (not self.ready) or (self.image.isNull()) : return # nothing to do here #self.profiler.enable() #dbg # Query the Color look-up table and build a list of the Green values # corresponding to each possible pixel value. Probably there are just # two colors so colortab is [0,255] but there could be more, depending # on how the PNG was defined, 16 or 32 or even 255 grayscale. colortab = [ int((self.image.color(c) >> 4) & 255) for c in range(self.image.colorCount()) ] ncols = self.image.width() # number of logical pixels across stride = (ncols + 3) & (-4) # number of bytes per scanline nrows = self.image.height() # number of pixels high vptr = self.image.bits() # uchar * bunch-o-pixel-bytes vptr.setsize(stride * nrows) # make the pointer indexable # Scan in from left and right to find the outermost dark spots. # Looking for single pixels yeilds too many false positives, so we # look for three adjacent pixels that sum to less than 32. # Most pages start with many lines of white pixels so in hopes of # establishing the outer edge early, we start at the middle, go to # the end, then do the top half. left_side = int(ncols/2) # leftmost dark spot seen so far # scan from the middle down for r in xrange(int(nrows/2)*stride, (nrows-1)*stride, stride) : pa, pb = 255, 255 # virtual white outside border for c in xrange(left_side): pc = colortab[ ord(vptr[c + r]) ] if (pa + pb + pc) < 32 : # black or dark gray pair left_side = c # new, further-left, left margin break # no need to look further on this line pa = pb pb = pc # scan from the top to the middle, hopefully left_side is small now for r in xrange(0, int(nrows/2)*stride, stride) : pa, pb = 255, 255 # virtual white outside border for c in xrange(left_side): pc = colortab[ ord(vptr[c + r]) ] if (pa + pb + pc) < 32 : # black or dark gray pair left_side = c # new, further-left, left margin break # no need to look further on this line pa = pb pb = pc # Now do the same for the right margin. right_side = int(ncols/2) # rightmost dark spot seen so far for r in xrange(int(nrows/2)*stride, (nrows-1)*stride, stride) : pa, pb = 255, 255 # virtual white outside border for c in xrange(ncols-1,right_side,-1) : pc = colortab[ ord(vptr[c + r]) ] if (pa + pb + pc) < 32 : # black or dark gray pair right_side = c # new, further-right, right margin break pa = pb pb = pc for r in xrange(0, int(nrows/2)*stride, stride) : pa, pb = 255, 255 # virtual white outside border for c in xrange(ncols-1,right_side,-1) : pc = colortab[ ord(vptr[c + r]) ] if (pa + pb + pc) < 32 : # black or dark gray pair right_side = c # new, further-right, right margin break pa = pb pb = pc # The area with color runs from left_side to right_side. How does # that compare to the size of our viewport? Scale to that and redraw. #print('ls {0} rs {1} vp {2}'.format(left_side,right_side,self.scarea.viewport().width())) text_size = right_side - left_side + 2 port_width = self.scarea.viewport().width() self.zoomFactor = max( self.minZoom, min( self.maxZoom, port_width / text_size ) ) # the next line signals newZoomFactor, which calls showPage. self.zlider.setValue(int(100*self.zoomFactor)) # Set the scrollbar to show the page from its left margin. self.scarea.horizontalScrollBar().setValue(int( left_side * self.zoomFactor) ) #self.profiler.disable() #dbg #pstats.Stats(self.profiler).print_stats() # dbg def zoomToHeight(self): if (not self.ready) or (self.image.isNull()) : return # nothing to do here # Query the Color look-up table and build a list of the Green values # corresponding to each possible pixel value. Probably there are just # two colors so colortab is [0,255] but there could be more, depending # on how the PNG was defined, 16 or 32 or even 255 grayscale. colortab = [ int((self.image.color(c) >> 4) & 255) for c in range(self.image.colorCount()) ] ncols = self.image.width() # number of logical pixels across stride = (ncols + 3) & (-4) # number of bytes per scanline nrows = self.image.height() # number of pixels high vptr = self.image.bits() # uchar * bunch-o-pixel-bytes vptr.setsize(stride * nrows) # make the pointer indexable # Scan in from top and bottom to find the outermost rows with # significant pixels. top_side = -1 # The uppermost row with a significant spot of black offset = 0 # vptr index to the first/next pixel row for r in range(nrows) : pa, pb = 255, 255 # virtual white outside border for c in range(ncols) : pc = colortab[ ord(vptr[offset + c]) ] if (pa + pb + pc) < 32 : # black or dark gray triplet top_side = r # that's the row, break # ..so stop scanning pa, pb = pb, pc if top_side >= 0 : # we hit break # ..so don't scan down any further offset += stride # continue to next row # top_side indexes the first row with a significant blot if top_side == -1 : # never found one: an all-white page. bug out. return bottom_side = nrows # The lowest row with a significant blot offset = stride * nrows # vptr index to last/next row of pixels for r in range(nrows,top_side,-1) : offset -= stride pa, pb = 255, 255 # virtual white outside border for c in range(ncols) : pc = colortab[ ord(vptr[offset + c]) ] if (pa + pb + pc) < 32 : # black or dark gray triplet bottom_side = r break pa, pb = pb, pc if bottom_side < nrows : # we hit break # bottom_side is the lowest row with significant pixels. It must be # < nrows, there is at least one row (top_side) with a dot in it. # However if the page is mostly white, don't zoom to that extent. if bottom_side < (top_side+100) : return # seems to be a mostly-white page, give up # The text area runs from scanline top_side to bottom_side. text_height = bottom_side - top_side + 1 port_height = self.scarea.viewport().height() self.zoomFactor = max( self.minZoom, min( self.maxZoom, port_height / text_height ) ) self.zlider.setValue(int(100*self.zoomFactor)) # signals newZoomFactor->showPage # Set the scrollbar to show the page from its top margin. self.scarea.verticalScrollBar().setValue(int( top_side * self.zoomFactor) ) # Re-implement the parent's keyPressEvent in order to provide zoom: # ctrl-plus increases the image size by 1.25 # ctrl-minus decreases the image size by 0.8 # Also trap pageup/dn and use to walk through images. # At this point we do not reposition the editor to match the page viewed. # we page up/dn but as soon as focus returns to the editor and the cursor # moves, this display will snap back to the edited page. As a user that # seems best, come over to Pngs and page ahead to see what's coming, then # back to the editor to read or type. def keyPressEvent(self, event): # assume we will not handle this key and clear its accepted flag event.ignore() # If we are initialized and have displayed some page, look at the key if self.ready: kkey = int( int(event.modifiers()) & IMC.keypadDeModifier) | int(event.key()) if kkey in IMC.zoomKeys : # ctl/cmd + or -, do the zoom event.accept() fac = (0.8) if (kkey == IMC.ctl_minus) else (1.25) fac *= self.zoomFactor # target zoom factor if (fac >= self.minZoom) and (fac <= self.maxZoom): # keep in bounds self.zoomFactor = fac self.zlider.setValue(int(100*fac)) self.showPage() elif (event.key() == Qt.Key_PageUp) or (event.key() == Qt.Key_PageDown) : event.accept() # real pgUp or pgDn, we do it fac = 1 if (event.key() == Qt.Key_PageDown) else -1 fac += self.lastIndex if (fac >= 0) and (fac < IMC.pageTable.size()) : # not off either end of the book, so, self.nextIndex = fac self.showPage() if not event.isAccepted() : # we don't do those, pass them on super(pngDisplay, self).keyPressEvent(event)
def get_box(scene_info): mode = scene_info.mode box_color = scene_info.box_color box_type = scene_info.box_type speaking = scene_info.speaking speaker_id = scene_info.speaker headshot = scene_info.headshot chapter = scene_info.chapter if box_color != common.BOX_COLORS.yellow and box_color != common.BOX_COLORS.green and box_color != common.BOX_COLORS.blue: box_color = common.BOX_COLORS.yellow out = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) out.fill(QColor(0, 0, 0, 0).rgba()) painter = QPainter(out) painter.setRenderHint(QPainter.Antialiasing, True) # Some commonality between the boxes. box = QImage() button = QImage() nametag_x = 0 nametag_y = 0 nametag_color = QColor(255, 255, 255, 255) nametag_vert = False if box_type == common.BOX_TYPES.flat: box = QImage(os.path.join(TEXTBOX_DIR, "box_gray.png")) button = QImage(os.path.join(TEXTBOX_DIR, "button_%s.png" % box_color)) nametag_x = 10 nametag_y = 176 nametag_color = QColor(255, 255, 255, 255) nametag_vert = False elif box_type == common.BOX_TYPES.novel: box = QImage(os.path.join(TEXTBOX_DIR, "box_novel.png")) elif box_type == common.BOX_TYPES.normal: if mode == common.SCENE_MODES.normal: box = QImage(os.path.join(TEXTBOX_DIR, "box.png")) button = QImage(os.path.join(TEXTBOX_DIR, "button_%s.png" % box_color)) nametag_x = 0 nametag_y = 220 nametag_color = QColor(50, 50, 50, 255) nametag_vert = True if not box.format() is QImage.Format_ARGB32_Premultiplied: box = box.convertToFormat(QImage.Format_ARGB32_Premultiplied) box_painter = QPainter(box) box_painter.setRenderHint(QPainter.Antialiasing, True) if speaker_id == 0: # Main character gets a special text box. namebox = QImage(os.path.join(TEXTBOX_DIR, "name_%s_mc.png" % box_color)) else: namebox = QImage(os.path.join(TEXTBOX_DIR, "name_%s.png" % box_color)) box_painter.drawImage(box.rect(), namebox, namebox.rect()) box_painter.end() elif mode == common.SCENE_MODES.trial: box_base = QImage(os.path.join(TRIAL_DIR, "trial_box.png")) banner = QImage(os.path.join(TRIAL_DIR, "trial_banner.png")) if speaker_id == 0: # Main character gets a special text box. namebox = QImage(os.path.join(TRIAL_DIR, "trial_name_mc.png")) else: namebox = QImage(os.path.join(TRIAL_DIR, "trial_name.png")) if not headshot == None: case_num = QImage(os.path.join(TRIAL_DIR, "case_%02d.png" % chapter)) headshot = QImage(os.path.join(TRIAL_DIR, "headshot", "%02d.png" % headshot)) underlay = QImage(os.path.join(TRIAL_DIR, "trial_headshot.png")) else: case_num = QImage() underlay = QImage() headshot = QImage() button = QImage(os.path.join(TRIAL_DIR, "button.png")) nametag_x = 12 nametag_y = 168 nametag_color = QColor(255, 255, 255, 255) nametag_vert = False box = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) box.fill(QColor(0, 0, 0, 0).rgba()) box_painter = QPainter(box) box_painter.setRenderHint(QPainter.Antialiasing, True) box_painter.drawImage(box.rect(), banner, banner.rect()) box_painter.drawImage(box.rect(), namebox, namebox.rect()) box_painter.drawImage(box.rect(), box_base, box_base.rect()) box_painter.drawImage(box.rect(), underlay, underlay.rect()) box_painter.drawImage(box.rect(), headshot, headshot.rect()) box_painter.drawImage(box.rect(), case_num, case_num.rect()) box_painter.end() else: box = QImage(IMG_W, IMG_H, QImage.Format_ARGB32_Premultiplied) box.fill(QColor(0, 0, 0, 0).rgba()) painter.drawImage(out.rect(), box, box.rect()) painter.drawImage(out.rect(), button, button.rect()) if not speaker_id == None: nametag = get_nametag(speaker_id, nametag_x, nametag_y, nametag_color, nametag_vert) painter.drawImage(out.rect(), nametag, nametag.rect()) painter.end() return out