Example #1
0
 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)
Example #2
0
 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)
Example #3
0
    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()
Example #4
0
    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)
Example #5
0
 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)
Example #6
0
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
Example #9
0
 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
Example #10
0
 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)
Example #12
0
    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
Example #13
0
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 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 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
Example #24
0
    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
Example #25
0
    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
Example #26
0
    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);
Example #28
0
	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
Example #29
0
	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
Example #33
0
    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
Example #36
0
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)
Example #37
0
	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
Example #39
0
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