示例#1
0
    def test_can_load_any_supported_image_format_when_allow_processing_is_true(
            self):
        image = self._createImage(600, 900)

        imageBytes = self._saveImage(image, "BMP")
        self.assertEqual(type(images.CoverImage(imageBytes)),
                         images.CoverImage)

        imageBytes = self._saveImage(image, "PNG")
        self.assertEqual(type(images.CoverImage(imageBytes)),
                         images.CoverImage)

        imageBytes = self._saveImage(image, "JPEG")
        self.assertEqual(type(images.CoverImage(imageBytes)),
                         images.CoverImage)
示例#2
0
    def test_image_with_wrong_dimensions_raises_exception_when_allow_processing_is_false(
            self):
        imageBytes = self._saveImage(self._createImage(50, 50))

        self.assertRaises(
            images.InvalidDimensionsError,
            lambda: images.CoverImage(imageBytes, allowProcessing=False))
示例#3
0
    def test_can_only_load_jpg_images_when_allow_processing_is_false(self):
        image = self._createImage(600, 900)

        imageBytes = self._saveImage(image, "BMP")
        self.assertRaises(
            ValueError,
            lambda: images.CoverImage(imageBytes, allowProcessing=False))

        imageBytes = self._saveImage(image, "PNG")
        self.assertRaises(
            ValueError,
            lambda: images.CoverImage(imageBytes, allowProcessing=False))

        imageBytes = self._saveImage(image, "JPEG")
        self.assertEqual(
            type(images.CoverImage(imageBytes, allowProcessing=False)),
            images.CoverImage)
示例#4
0
    def test_cannot_load_progressive_image_when_allow_processing_is_false(
            self):
        imageBytes = self._saveImage(self._createImage(600, 900),
                                     progressive=True)

        self.assertRaises(
            images.ProgressiveImageError,
            lambda: images.CoverImage(imageBytes, allowProcessing=False))
示例#5
0
    def test_image_with_wrong_dimensions_is_scaled_when_allow_processing_is_true(
            self):
        imageBytes = self._saveImage(self._createImage(500, 480))

        coverImage = images.CoverImage(imageBytes)
        resizedCoverImage = Image.open(io.BytesIO(coverImage.toBytes()))

        self.assertEqual(resizedCoverImage.size, (600, 900))
示例#6
0
    def test_change_image_quality_always_operates_in_original_image(self):
        image = self._createImage(50, 50)

        data = image.load()

        # Modifico los pixeles con diferentes colores para incrementar de tamaño la imagen.
        for y in range(image.size[1]):
            for x in range(image.size[0]):
                data[x, y] = (0, 0, random.randint(0, 255))

        imageBytes = self._saveImage(image)
        coverImage1 = images.CoverImage(imageBytes)
        coverImage2 = images.CoverImage(imageBytes)
        coverImage1.setQuality(50)
        coverImage1.setQuality(10)
        coverImage2.setQuality(10)

        self.assertEqual(coverImage1.toBytes(), coverImage2.toBytes())
示例#7
0
    def test_can_load_image_in_mode_P_and_save_it_as_jpg(self):
        # Por defecto, _saveImage guarda la imagen en formato jpg, pero jpg no soporta el modo "P", por eso
        # es que debo guardarla como png, que para propósitos del test no tiene importancia: lo único que me
        # interesa es que CoverImage sea capaz de abrir una imagen en modo "P" y poder guardarla como jpg.
        imageBytes = self._saveImage(self._createImage(600, 900, mode="P"),
                                     imageFormat="PNG")

        coverImage = images.CoverImage(imageBytes)

        self.assertTrue(len(coverImage.toBytes()) > 0)
示例#8
0
    def test_logo_insertion(self):
        imageBytes = self._saveImage(self._createImage(100, 100))

        coverImage = images.CoverImage(imageBytes)
        coverImageWithNoLogoBytes = coverImage.toBytes()

        # ¡Cuidado el logo que elijo para hacer el test! Por defecto, al crear un objeto Image, este
        # se llena de pixeles negros, con lo cual si le inserto el logo negro, el test va a fallar! La otra
        # opción sería llenar el Image con pixeles de otro color si quisiera probar con el logo negro...
        coverImage.insertLogo(images.CoverImage.WHITE_LOGO)

        coverImageWithLogoBytes = coverImage.toBytes()

        self.assertNotEqual(coverImageWithLogoBytes, coverImageWithNoLogoBytes)
示例#9
0
    def test_image_is_not_modified_when_allow_processing_is_false(self):
        image = self._createImage(600, 900)
        data = image.load()

        data[0, 0] = (123, 21, 90)
        data[0, 1] = (150, 232, 9)
        data[0, 2] = (111, 13, 45)
        data[0, 3] = (8, 214, 78)

        imageBytes = self._saveImage(image)

        self.assertEqual(
            imageBytes,
            images.CoverImage(imageBytes, allowProcessing=False).toBytes())
示例#10
0
    def test_image_size_too_big_raises_exception_when_allow_processing_is_false(
            self):
        image = self._createImage(600, 900)

        data = image.load()

        # Modifico los pixeles con diferentes colores para incrementar de tamaño la imagen.
        for y in range(image.size[1]):
            for x in range(image.size[0]):
                data[x, y] = (0, 0, random.randint(0, 255))

        imageBytes = self._saveImage(image)

        self.assertRaises(
            images.MaxSizeExceededError,
            lambda: images.CoverImage(imageBytes, allowProcessing=False))
示例#11
0
    def test_image_quality_is_automatically_lowered_when_size_exceeds_max_size_and_allow_processing_is_true(
            self):
        image = self._createImage(600, 600)

        data = image.load()

        # Modifico los pixeles con diferentes colores para incrementar de tamaño la imagen.
        for y in range(image.size[1]):
            for x in range(image.size[0]):
                data[x, y] = (0, 0, random.randint(0, 255))

        imageBytes = self._saveImage(image)
        coverImage = images.CoverImage(imageBytes)

        self.assertLessEqual(len(coverImage.toBytes()),
                             images.CoverImage.MAX_SIZE_IN_BYTES)
        self.assertNotEqual(coverImage.quality(), 100)
示例#12
0
    def test_cover_for_web(self):
        image = self._createImage(600, 900)

        data = image.load()

        # Modifico los pixeles con diferentes colores para incrementar de tamaño la imagen.
        for y in range(image.size[1]):
            for x in range(image.size[0]):
                data[x, y] = (random.randint(0, 255), random.randint(0, 255),
                              random.randint(0, 255))

        imageBytes = self._saveImage(image)
        coverImage = images.CoverImage(imageBytes)
        coverImageBytesForWeb = coverImage.toBytesForWeb()
        coverImageForWeb = Image.open(io.BytesIO(coverImageBytesForWeb))

        self.assertEqual(coverImageForWeb.size, (400, 600))
        self.assertLessEqual(len(coverImageBytesForWeb), 100 * 1000)
示例#13
0
    def test_image_quality_is_not_automatically_lowered_when_was_manually_set_and_its_size_is_below_max_size_and_allow_processing_is_true(
            self):
        image = self._createImage(50, 50)

        data = image.load()

        # Modifico los pixeles con diferentes colores para incrementar de tamaño la imagen.
        for y in range(image.size[1]):
            for x in range(image.size[0]):
                data[x, y] = (random.randint(0, 255), random.randint(0, 255),
                              random.randint(0, 255))

        imageBytes = self._saveImage(image)
        coverImage = images.CoverImage(imageBytes)
        coverImage.setQuality(20)
        quality = coverImage.quality()

        self.assertEqual(coverImage.size(), len(coverImage.toBytes()))
        self.assertEqual(coverImage.quality(), quality)
示例#14
0
    def _changeCoverImage(self):
        settings = settings_store.SettingsStore()

        allowedFormatsToOpen = (
            "*.{0}".format(f) for f in images.CoverImage.allowedFormatsToOpen(
                settings.allowImageProcessing))
        imagesFilter = "Imágenes ({0})".format(" ".join(allowedFormatsToOpen))

        imageName = QtGui.QFileDialog.getOpenFileName(self,
                                                      "Seleccionar Imagen",
                                                      filter=imagesFilter)

        if imageName:
            try:
                image = images.CoverImage(
                    imageName, allowProcessing=settings.allowImageProcessing)
            except images.InvalidDimensionsError:
                gui_utils.displayStdErrorDialog(
                    "La imagen de cubierta seleccionada no tiene las dimensiones requeridas, que deben ser "
                    "de {0}px de ancho y {1}px de alto. Si desea que la imagen se redimensione "
                    "automáticamente, habilite la opción para permitir el procesamiento de las imágenes desde el "
                    "menú Preferencias.".format(images.CoverImage.WIDTH,
                                                images.CoverImage.HEIGHT))
                return
            except images.MaxSizeExceededError:
                gui_utils.displayStdErrorDialog(
                    "La imagen de cubierta excede el tamaño máximo permitido, que debe "
                    "ser menor o igual a {0} kB. Si desea que la calidad de la imagen se ajuste automáticamente "
                    "para reducir su tamaño, habilite la opción para permitir el procesamiento de las imágenes "
                    "desde el menú Preferencias.".format(
                        images.CoverImage.MAX_SIZE_IN_BYTES // 1000))
                return
            except images.ProgressiveImageError:
                gui_utils.displayStdErrorDialog(
                    "La imagen de cubierta no puede ser abierta porque fue guardada en modo progresivo. Guárdela de "
                    "manera normal y vuelva a abrirla, o habilite la opción para permitir el procesamiento de las "
                    "imágenes desde el menú Preferencias.")
                return

            self.setCoverImage(image)

            if settings.allowImageProcessing:
                self.editCoverImageButton.setEnabled(True)
示例#15
0
    def _addEpubBaseFiles(self, outputEpub):
        synopsis = self._metadata.synopsis or ebook_metadata.Metadata.DEFAULT_SYNOPSIS
        title = self._metadata.title or ebook_metadata.Metadata.DEFAULT_TITLE
        editor = self._metadata.editor or ebook_metadata.Metadata.DEFAULT_EDITOR
        coverModification = self._metadata.coverModification or ebook_metadata.Metadata.DEFAULT_COVER_MODIFICATION
        coverImage = self._metadata.coverImage or images.CoverImage(
            files.EpubBaseFiles.getFile(
                files.EpubBaseFiles.COVER_IMAGE_FILENAME))
        publicationYear = self._metadata.publicationDate.year if self._metadata.publicationDate else ""
        authors = self._metadata.authors or [
            ebook_metadata.Person(ebook_metadata.Metadata.DEFAULT_AUTHOR,
                                  ebook_metadata.Metadata.DEFAULT_AUTHOR)
        ]
        author = self._getPersonsListAsText(authors)[0]
        translator = self._getPersonsListAsText(self._metadata.translators)[0]
        ilustrator = self._getPersonsListAsText(self._metadata.ilustrators)[0]

        # Agrego los xhtml requeridos, excepto autor.xhtml, que debe ir despúes de las secciones.
        outputEpub.addHtmlData(
            files.EpubBaseFiles.COVER_FILENAME,
            files.EpubBaseFiles.getFile(files.EpubBaseFiles.COVER_FILENAME))
        outputEpub.addHtmlData(files.EpubBaseFiles.SYNOPSIS_FILENAME,
                               files.EpubBaseFiles.getSynopsis(synopsis))
        outputEpub.addHtmlData(
            files.EpubBaseFiles.TITLE_FILENAME,
            files.EpubBaseFiles.getTitle(author, title,
                                         self._metadata.subtitle, editor,
                                         self._metadata.collectionName,
                                         self._metadata.subCollectionName,
                                         self._metadata.collectionVolume))
        outputEpub.addHtmlData(
            files.EpubBaseFiles.INFO_FILENAME,
            files.EpubBaseFiles.getInfo(self._metadata.originalTitle, author,
                                        publicationYear, translator,
                                        ilustrator,
                                        self._metadata.coverDesigner,
                                        coverModification, editor))

        if self._metadata.dedication or self._options.includeOptionalFiles:
            dedication = self._metadata.dedication or ebook_metadata.Metadata.DEFAULT_DEDICATION
            outputEpub.addHtmlData(
                files.EpubBaseFiles.DEDICATION_FILENAME,
                files.EpubBaseFiles.getDedication(dedication))

        outputEpub.addImageData(files.EpubBaseFiles.COVER_IMAGE_FILENAME,
                                coverImage.toBytes())

        # Agrego el resto de los archivos del epubbase.
        outputEpub.addImageData(
            files.EpubBaseFiles.EPL_LOGO_FILENAME,
            files.EpubBaseFiles.getFile(files.EpubBaseFiles.EPL_LOGO_FILENAME))
        outputEpub.addImageData(
            files.EpubBaseFiles.EX_LIBRIS_FILENAME,
            files.EpubBaseFiles.getFile(
                files.EpubBaseFiles.EX_LIBRIS_FILENAME))
        outputEpub.addStyleData(
            files.EpubBaseFiles.STYLE_FILENAME,
            files.EpubBaseFiles.getFile(files.EpubBaseFiles.STYLE_FILENAME))
        outputEpub.addMetaFile(
            files.EpubBaseFiles.APPLE_XML,
            files.EpubBaseFiles.getFile(files.EpubBaseFiles.APPLE_XML))
示例#16
0
    def test_can_load_image_when_dimensions_and_size_are_ok_and_allow_processing_is_false(
            self):
        imageBytes = self._saveImage(self._createImage(600, 900))
        coverImage = images.CoverImage(imageBytes, allowProcessing=False)

        self.assertEqual(type(coverImage), images.CoverImage)
示例#17
0
    def test_can_load_progressive_image_when_allow_processing_is_true(self):
        imageBytes = self._saveImage(self._createImage(600, 900),
                                     progressive=True)

        self.assertEqual(type(images.CoverImage(imageBytes)),
                         images.CoverImage)