Пример #1
0
    def test_vips(self):
        self.save_load_file(".v", "", self.colour, 0)

        # check we can save and restore metadata
        filename = temp_filename(self.tempdir, ".v")
        self.colour.write_to_file(filename)
        x = pyvips.Image.new_from_file(filename)
        before_exif = self.colour.get("exif-data")
        after_exif = x.get("exif-data")

        assert len(before_exif) == len(after_exif)
        for i in range(len(before_exif)):
            assert before_exif[i] == after_exif[i]

        # https://github.com/libvips/libvips/issues/1847
        filename = temp_filename(self.tempdir, ".v")
        x = pyvips.Image.black(16, 16) + 128
        x.write_to_file(filename)

        x = pyvips.Image.new_from_file(filename)
        assert x.width == 16
        assert x.height == 16
        assert x.bands == 1
        assert x.avg() == 128

        x = None
Пример #2
0
    def test_jpeg(self):
        def jpeg_valid(im):
            a = im(10, 10)
            assert_almost_equal_objects(a, [6, 5, 3])
            profile = im.get("icc-profile-data")
            assert len(profile) == 1352
            assert im.width == 1024
            assert im.height == 768
            assert im.bands == 3

        self.file_loader("jpegload", JPEG_FILE, jpeg_valid)
        self.save_load("%s.jpg", self.mono)
        self.save_load("%s.jpg", self.colour)

        self.buffer_loader("jpegload_buffer", JPEG_FILE, jpeg_valid)
        self.save_load_buffer("jpegsave_buffer", "jpegload_buffer",
                              self.colour, 80)

        # see if we have exif parsing: our test image has this field
        x = pyvips.Image.new_from_file(JPEG_FILE)
        if x.get_typeof("exif-ifd0-Orientation") != 0:
            # we need a copy of the image to set the new metadata on
            # otherwise we get caching problems

            # can set, save and load new orientation
            x = pyvips.Image.new_from_file(JPEG_FILE)
            x = x.copy()
            x.set("orientation", 2)
            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)
            x = pyvips.Image.new_from_file(filename)
            y = x.get("orientation")
            assert y == 2

            # can remove orientation, save, load again, orientation
            # has reset
            x.remove("orientation")
            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)
            x = pyvips.Image.new_from_file(filename)
            y = x.get("orientation")
            assert y == 1

            # autorotate load works
            filename = temp_filename(self.tempdir, '.jpg')
            x = pyvips.Image.new_from_file(JPEG_FILE)
            x = x.copy()
            x.set("orientation", 6)
            x.write_to_file(filename)
            x1 = pyvips.Image.new_from_file(filename)
            x2 = pyvips.Image.new_from_file(filename, autorotate=True)
            assert x1.width == x2.height
            assert x1.height == x2.width
Пример #3
0
    def test_magicksave(self):
        # save to a file and load again ... we can't use save_load_file since
        # we want to make sure we use magickload/save
        # don't use BMP - GraphicsMagick always adds an alpha
        # don't use TIF - IM7 will save as 16-bit
        filename = temp_filename(self.tempdir, ".jpg")

        self.colour.magicksave(filename)
        x = pyvips.Image.magickload(filename)

        assert self.colour.width == x.width
        assert self.colour.height == x.height
        assert self.colour.bands == x.bands
        max_diff = (self.colour - x).abs().max()
        assert max_diff < 60

        self.save_load_buffer("magicksave_buffer",
                              "magickload_buffer",
                              self.colour,
                              60,
                              format="JPG")

        # try an animation
        if have("gifload"):
            x1 = pyvips.Image.new_from_file(GIF_ANIM_FILE, n=-1)
            w1 = x1.magicksave_buffer(format="GIF")
            x2 = pyvips.Image.new_from_buffer(w1, "", n=-1)
            assert x1.get("delay") == x2.get("delay")
            assert x1.get("page-height") == x2.get("page-height")
            # magicks vary in how they handle this ... just pray we are close
            assert abs(x1.get("gif-loop") - x2.get("gif-loop")) < 5
Пример #4
0
    def test_gifload(self):
        def gif_valid(im):
            a = im(10, 10)
            assert_almost_equal_objects(a, [33])
            assert im.width == 159
            assert im.height == 203
            assert im.bands == 1

        self.file_loader("gifload", GIF_FILE, gif_valid)
        self.buffer_loader("gifload_buffer", GIF_FILE, gif_valid)

        # 'n' param added in 8.5
        if pyvips.at_least_libvips(8, 5):
            x1 = pyvips.Image.new_from_file(GIF_ANIM_FILE)
            x2 = pyvips.Image.new_from_file(GIF_ANIM_FILE, n=2)
            assert x2.height == 2 * x1.height
            page_height = x2.get("page-height")
            assert page_height == x1.height

            x2 = pyvips.Image.new_from_file(GIF_ANIM_FILE, n=-1)
            assert x2.height == 5 * x1.height
            # our test gif has delay 0 for the first frame set in error
            assert x2.get("delay") == [0, 50, 50, 50, 50]

            x2 = pyvips.Image.new_from_file(GIF_ANIM_FILE, page=1, n=-1)
            assert x2.height == 4 * x1.height

            animation = pyvips.Image.new_from_file(GIF_ANIM_FILE, n=-1)
            filename = temp_filename(self.tempdir, '.png')
            animation.write_to_file(filename)
            # Uncomment to see output file
            # animation.write_to_file('cogs.png')

            assert filecmp.cmp(GIF_ANIM_EXPECTED_PNG_FILE, filename, shallow=False)
Пример #5
0
    def test_autorot(self):
        rotation_images = os.path.join(IMAGES, 'rotation')
        files = os.listdir(rotation_images)
        files.sort()

        meta = {
            0: {'w': 290, 'h': 442},
            1: {'w': 308, 'h': 410},
            2: {'w': 308, 'h': 410},
            3: {'w': 308, 'h': 410},
            4: {'w': 308, 'h': 410},
            5: {'w': 231, 'h': 308},
            6: {'w': 231, 'h': 308},
            7: {'w': 231, 'h': 308},
            8: {'w': 231, 'h': 308},
        }

        i = 0
        for f in files:
            if '.autorot.' not in f and not f.startswith('.'):
                source_filename = os.path.join(rotation_images, f)

                actual_filename = temp_filename(self.tempdir, '.jpg')

                pyvips.Image.new_from_file(source_filename).autorot().write_to_file(actual_filename)

                actual = pyvips.Image.new_from_file(actual_filename)

                assert actual.width == meta[i]['w']
                assert actual.height == meta[i]['h']
                assert actual.get('orientation') if actual.get_typeof('orientation') else None is None
                i = i + 1
Пример #6
0
    def test_save_file(self):
        filename = temp_filename(self.tempdir, '.jpg')

        im = pyvips.Image.black(10, 20)
        im.write_to_file(filename)
        assert os.path.isfile(filename)

        os.remove(filename)
Пример #7
0
    def test_image_write_to_stream_file(self):
        filename = temp_filename(self.tempdir, ".jpg")
        x = pyvips.Streamo.new_to_file(filename)
        self.colour.write_to_stream(x, ".jpg")
        with open(filename, 'rb') as f:
            data = f.read()
        data2 = self.colour.write_to_buffer(".jpg")

        assert data == data2
Пример #8
0
    def test_gifload_animation_dispose_previous(self):
        animation = pyvips.Image.new_from_file(GIF_ANIM_DISPOSE_PREVIOUS_FILE, n=-1)

        filename = temp_filename(self.tempdir, '.png')
        animation.write_to_file(filename)

        # Uncomment to see output file
        # animation.write_to_file('dispose-previous.png')

        assert filecmp.cmp(GIF_ANIM_DISPOSE_PREVIOUS_EXPECTED_PNG_FILE, filename, shallow=False)
Пример #9
0
    def test_gifload_animation_dispose_background(self):
        animation = pyvips.Image.new_from_file(GIF_ANIM_DISPOSE_BACKGROUND_FILE, n=-1)

        filename = temp_filename(self.tempdir, '.png')
        animation.write_to_file(filename)

        # Uncomment to see output file
        # animation.write_to_file('dispose-background.png')

        assert filecmp.cmp(GIF_ANIM_DISPOSE_BACKGROUND_EXPECTED_PNG_FILE, filename, shallow=False)
Пример #10
0
    def test_connection(self):
        source = pyvips.Source.new_from_file(JPEG_FILE)
        image = pyvips.Image.new_from_source(source, '', access='sequential')
        filename = temp_filename(self.tempdir, '.png')
        target = pyvips.Target.new_to_file(filename)
        image.write_to_target(target, '.png')

        image = pyvips.Image.new_from_file(JPEG_FILE, access='sequential')
        image2 = pyvips.Image.new_from_file(filename, access='sequential')

        assert (image - image2).abs().max() < 10
Пример #11
0
    def test_load_file(self):
        filename = temp_filename(self.tempdir, '.jpg')

        im = pyvips.Image.black(10, 20)
        im.write_to_file(filename)

        x = pyvips.Image.new_from_file(filename)
        assert x.width == 10
        assert x.height == 20
        assert x.bands == 1

        os.remove(x.filename)
Пример #12
0
    def save_load_file(self, format, options, im, max_diff=0):
        # yuk!
        # but we can't set format parameters for pyvips.Image.new_temp_file()
        filename = temp_filename(self.tempdir, format)

        im.write_to_file(filename + options)
        x = pyvips.Image.new_from_file(filename)

        assert im.width == x.width
        assert im.height == x.height
        assert im.bands == x.bands
        assert (im - x).abs().max() <= max_diff
        x = None
Пример #13
0
    def save_buffer_tempfile(self, saver, suf, im, max_diff=0):
        filename = temp_filename(self.tempdir, suf)

        buf = pyvips.Operation.call(saver, im)
        f = open(filename, 'wb')
        f.write(buf)
        f.close()

        x = pyvips.Image.new_from_file(filename)

        assert im.width == x.width
        assert im.height == x.height
        assert im.bands == x.bands
        assert (im - x).abs().max() <= max_diff
Пример #14
0
    def save_load_file(self, format, options, im, thresh):
        # yuk!
        # but we can't set format parameters for pyvips.Image.new_temp_file()
        filename = temp_filename(self.tempdir, format)

        im.write_to_file(filename + options)
        x = pyvips.Image.new_from_file(filename)

        assert im.width == x.width
        assert im.height == x.height
        assert im.bands == x.bands
        max_diff = (im - x).abs().max()
        assert max_diff <= thresh
        x = None
Пример #15
0
    def save_buffer_tempfile(self, saver, suf, im, max_diff=0):
        filename = temp_filename(self.tempdir, suf)

        buf = pyvips.Operation.call(saver, im)
        f = open(filename, 'wb')
        f.write(buf)
        f.close()

        x = pyvips.Image.new_from_file(filename)

        assert im.width == x.width
        assert im.height == x.height
        assert im.bands == x.bands
        assert (im - x).abs().max() <= max_diff
Пример #16
0
    def test_vips(self):
        self.save_load_file(".v", "", self.colour, 0)

        # check we can save and restore metadata
        filename = temp_filename(self.tempdir, ".v")
        self.colour.write_to_file(filename)
        x = pyvips.Image.new_from_file(filename)
        before_exif = self.colour.get("exif-data")
        after_exif = x.get("exif-data")

        assert len(before_exif) == len(after_exif)
        for i in range(len(before_exif)):
            assert before_exif[i] == after_exif[i]

        x = None
Пример #17
0
    def test_vips(self):
        self.save_load_file(".v", "", self.colour, 0)

        # check we can save and restore metadata
        filename = temp_filename(self.tempdir, ".v")
        self.colour.write_to_file(filename)
        x = pyvips.Image.new_from_file(filename)
        before_exif = self.colour.get("exif-data")
        after_exif = x.get("exif-data")

        assert len(before_exif) == len(after_exif)
        for i in range(len(before_exif)):
            assert before_exif[i] == after_exif[i]

        x = None
Пример #18
0
    def test_magicksave(self):
        # save to a file and load again ... we can't use save_load_file since
        # we want to make sure we use magickload/save 
        # don't use BMP - GraphicsMagick always adds an alpha
        # don't use TIF - IM7 will save as 16-bit
        filename = temp_filename(self.tempdir, ".jpg")

        self.colour.magicksave(filename)
        x = pyvips.Image.magickload(filename)

        assert self.colour.width == x.width
        assert self.colour.height == x.height
        assert self.colour.bands == x.bands
        max_diff = (self.colour - x).abs().max()
        assert max_diff < 40

        self.save_load_buffer("magicksave_buffer", "magickload_buffer",
                              self.colour, 40, format="JPG")
Пример #19
0
    def test_magicksave(self):
        # save to a file and load again ... we can't use save_load_file since
        # we want to make sure we use magickload/save 
        # don't use BMP - GraphicsMagick always adds an alpha
        # don't use TIF - IM7 will save as 16-bit
        filename = temp_filename(self.tempdir, ".jpg")

        self.colour.magicksave(filename)
        x = pyvips.Image.magickload(filename)

        assert self.colour.width == x.width
        assert self.colour.height == x.height
        assert self.colour.bands == x.bands
        max_diff = (self.colour - x).abs().max()
        assert max_diff < 40

        self.save_load_buffer("magicksave_buffer", "magickload_buffer",
                              self.colour, 40, format="JPG")
Пример #20
0
    def test_target_custom(self):
        filename = temp_filename(self.tempdir, '.png')
        output_file = open(filename, "wb")

        def write_handler(chunk):
            return output_file.write(chunk)

        def finish_handler():
            output_file.close()

        target = pyvips.TargetCustom()
        target.on_write(write_handler)
        target.on_finish(finish_handler)

        image = pyvips.Image.new_from_file(JPEG_FILE, access='sequential')
        image.write_to_target(target, '.png')

        image = pyvips.Image.new_from_file(JPEG_FILE, access='sequential')
        image2 = pyvips.Image.new_from_file(filename, access='sequential')

        assert (image - image2).abs().max() == 0
Пример #21
0
    def test_dzsave(self):
        # dzsave is hard to test, there are so many options
        # test each option separately and hope they all function together
        # correctly

        # default deepzoom layout ... we must use png here, since we want to
        # test the overlap for equality
        filename = temp_filename(self.tempdir, '')
        self.colour.dzsave(filename, suffix=".png")

        # test horizontal overlap ... expect 256 step, overlap 1
        x = pyvips.Image.new_from_file(filename + "_files/10/0_0.png")
        assert x.width == 255
        y = pyvips.Image.new_from_file(filename + "_files/10/1_0.png")
        assert y.width == 256

        # the right two columns of x should equal the left two columns of y
        left = x.crop(x.width - 2, 0, 2, x.height)
        right = y.crop(0, 0, 2, y.height)
        assert (left - right).abs().max() == 0

        # test vertical overlap
        assert x.height == 255
        y = pyvips.Image.new_from_file(filename + "_files/10/0_1.png")
        assert y.height == 256

        # the bottom two rows of x should equal the top two rows of y
        top = x.crop(0, x.height - 2, x.width, 2)
        bottom = y.crop(0, 0, y.width, 2)
        assert (top - bottom).abs().max() == 0

        # there should be a bottom layer
        x = pyvips.Image.new_from_file(filename + "_files/0/0_0.png")
        assert x.width == 1
        assert x.height == 1

        # 10 should be the final layer
        assert not os.path.isdir(filename + "_files/11")

        # default google layout
        filename = temp_filename(self.tempdir, '')
        self.colour.dzsave(filename, layout="google")

        # test bottom-right tile ... default is 256x256 tiles, overlap 0
        x = pyvips.Image.new_from_file(filename + "/2/2/3.jpg")
        assert x.width == 256
        assert x.height == 256
        assert not os.path.exists(filename + "/2/2/4.jpg")
        assert not os.path.exists(filename + "/3")
        x = pyvips.Image.new_from_file(filename + "/blank.png")
        assert x.width == 256
        assert x.height == 256

        # google layout with overlap ... verify that we clip correctly

        # overlap 1, 510x510 pixels, 256 pixel tiles, should be exactly 2x2
        # tiles, though in fact the bottom and right edges will be white
        filename = temp_filename(self.tempdir, '')
        self.colour.crop(0, 0, 510, 510).dzsave(filename,
                                                layout="google",
                                                overlap=1,
                                                depth="one")

        x = pyvips.Image.new_from_file(filename + "/0/1/1.jpg")
        assert x.width == 256
        assert x.height == 256
        assert not os.path.exists(filename + "/0/2/2.jpg")

        # with 511x511, it'll fit exactly into 2x2 -- we we actually generate
        # 3x3, since we output the overlaps
        filename = temp_filename(self.tempdir, '')
        self.colour.crop(0, 0, 511, 511).dzsave(filename,
                                                layout="google",
                                                overlap=1,
                                                depth="one")

        x = pyvips.Image.new_from_file(filename + "/0/2/2.jpg")
        assert x.width == 256
        assert x.height == 256
        assert not os.path.exists(filename + "/0/3/3.jpg")

        # default zoomify layout
        filename = temp_filename(self.tempdir, '')
        self.colour.dzsave(filename, layout="zoomify")

        # 256x256 tiles, no overlap
        assert os.path.exists(filename + "/ImageProperties.xml")
        x = pyvips.Image.new_from_file(filename + "/TileGroup0/2-3-2.jpg")
        assert x.width == 256
        assert x.height == 256

        # test zip output
        filename = temp_filename(self.tempdir, '.zip')
        self.colour.dzsave(filename)
        assert os.path.exists(filename)
        assert not os.path.exists(filename + "_files")
        assert not os.path.exists(filename + ".dzi")

        # test compressed zip output
        filename2 = temp_filename(self.tempdir, '.zip')
        self.colour.dzsave(filename2, compression=-1)
        assert os.path.exists(filename2)
        assert os.path.getsize(filename2) < os.path.getsize(filename)

        # test suffix
        filename = temp_filename(self.tempdir, '')
        self.colour.dzsave(filename, suffix=".png")

        x = pyvips.Image.new_from_file(filename + "_files/10/0_0.png")
        assert x.width == 255

        # test overlap
        filename = temp_filename(self.tempdir, '')
        self.colour.dzsave(filename, overlap=200)

        y = pyvips.Image.new_from_file(filename + "_files/10/1_1.jpeg")
        assert y.width == 654

        # test tile-size
        filename = temp_filename(self.tempdir, '')
        self.colour.dzsave(filename, tile_size=512)

        y = pyvips.Image.new_from_file(filename + "_files/10/0_0.jpeg")
        assert y.width == 513
        assert y.height == 513

        # test save to memory buffer
        filename = temp_filename(self.tempdir, '.zip')
        base = os.path.basename(filename)
        root, ext = os.path.splitext(base)

        self.colour.dzsave(filename)
        with open(filename, 'rb') as f:
            buf1 = f.read()
        buf2 = self.colour.dzsave_buffer(basename=root)
        assert len(buf1) == len(buf2)

        # we can't test the bytes are exactly equal -- the timestamps will
        # be different

        # added in 8.7
        buf = self.colour.dzsave_buffer(region_shrink="mean")
        buf = self.colour.dzsave_buffer(region_shrink="mode")
        buf = self.colour.dzsave_buffer(region_shrink="median")
Пример #22
0
    def test_tiff(self):
        def tiff_valid(im):
            a = im(10, 10)
            assert_almost_equal_objects(a, [38671.0, 33914.0, 26762.0])
            assert im.width == 290
            assert im.height == 442
            assert im.bands == 3

        self.file_loader("tiffload", TIF_FILE, tiff_valid)
        self.buffer_loader("tiffload_buffer", TIF_FILE, tiff_valid)
        if pyvips.at_least_libvips(8, 5):
            self.save_load_buffer("tiffsave_buffer", "tiffload_buffer",
                                  self.colour)
        self.save_load("%s.tif", self.mono)
        self.save_load("%s.tif", self.colour)
        self.save_load("%s.tif", self.cmyk)

        self.save_load("%s.tif", self.onebit)
        self.save_load_file(".tif", "[squash]", self.onebit, 0)
        self.save_load_file(".tif", "[miniswhite]", self.onebit, 0)
        self.save_load_file(".tif", "[squash,miniswhite]", self.onebit, 0)

        self.save_load_file(".tif", "[profile={0}]".format(SRGB_FILE),
                            self.colour, 0)
        self.save_load_file(".tif", "[tile]", self.colour, 0)
        self.save_load_file(".tif", "[tile,pyramid]", self.colour, 0)
        self.save_load_file(".tif", "[tile,pyramid,compression=jpeg]",
                            self.colour, 80)
        self.save_load_file(".tif", "[bigtiff]", self.colour, 0)
        self.save_load_file(".tif", "[compression=jpeg]", self.colour, 80)
        self.save_load_file(".tif", "[tile,tile-width=256]", self.colour, 10)

        filename = temp_filename(self.tempdir, '.tif')
        x = pyvips.Image.new_from_file(TIF_FILE)
        x = x.copy()
        x.set("orientation", 2)
        x.write_to_file(filename)
        x = pyvips.Image.new_from_file(filename)
        y = x.get("orientation")
        assert y == 2

        filename = temp_filename(self.tempdir, '.tif')
        x = pyvips.Image.new_from_file(TIF_FILE)
        x = x.copy()
        x.set("orientation", 2)
        x.write_to_file(filename)
        x = pyvips.Image.new_from_file(filename)
        y = x.get("orientation")
        assert y == 2
        x.remove("orientation")

        filename = temp_filename(self.tempdir, '.tif')
        x.write_to_file(filename)
        x = pyvips.Image.new_from_file(filename)
        y = x.get("orientation")
        assert y == 1

        filename = temp_filename(self.tempdir, '.tif')
        x = pyvips.Image.new_from_file(TIF_FILE)
        x = x.copy()
        x.set("orientation", 6)
        x.write_to_file(filename)
        x1 = pyvips.Image.new_from_file(filename)
        x2 = pyvips.Image.new_from_file(filename, autorotate=True)
        assert x1.width == x2.height
        assert x1.height == x2.width

        # OME support in 8.5
        x = pyvips.Image.new_from_file(OME_FILE)
        assert x.width == 439
        assert x.height == 167
        page_height = x.height

        x = pyvips.Image.new_from_file(OME_FILE, n=-1)
        assert x.width == 439
        assert x.height == page_height * 15

        x = pyvips.Image.new_from_file(OME_FILE, page=1, n=-1)
        assert x.width == 439
        assert x.height == page_height * 14

        x = pyvips.Image.new_from_file(OME_FILE, page=1, n=2)
        assert x.width == 439
        assert x.height == page_height * 2

        x = pyvips.Image.new_from_file(OME_FILE, n=-1)
        assert x(0, 166)[0] == 96
        assert x(0, 167)[0] == 0
        assert x(0, 168)[0] == 1

        filename = temp_filename(self.tempdir, '.tif')
        x.write_to_file(filename)

        x = pyvips.Image.new_from_file(filename, n=-1)
        assert x.width == 439
        assert x.height == page_height * 15
        assert x(0, 166)[0] == 96
        assert x(0, 167)[0] == 0
        assert x(0, 168)[0] == 1

        # pyr save to buffer added in 8.6
        x = pyvips.Image.new_from_file(TIF_FILE)
        buf = x.tiffsave_buffer(tile=True, pyramid=True)
        filename = temp_filename(self.tempdir, '.tif')
        x.tiffsave(filename, tile=True, pyramid=True)
        with open(filename, 'rb') as f:
            buf2 = f.read()
        assert len(buf) == len(buf2)

        a = pyvips.Image.new_from_buffer(buf, "", page=2)
        b = pyvips.Image.new_from_buffer(buf2, "", page=2)
        assert a.width == b.width
        assert a.height == b.height
        assert a.avg() == b.avg()

        # region-shrink added in 8.7
        x = pyvips.Image.new_from_file(TIF_FILE)
        buf = x.tiffsave_buffer(tile=True, pyramid=True, region_shrink="mean")
        buf = x.tiffsave_buffer(tile=True, pyramid=True, region_shrink="mode")
        buf = x.tiffsave_buffer(tile=True,
                                pyramid=True,
                                region_shrink="median")
Пример #23
0
    def test_jpeg(self):
        def jpeg_valid(im):
            a = im(10, 10)
            assert_almost_equal_objects(a, [6, 5, 3])
            profile = im.get("icc-profile-data")
            assert len(profile) == 1352
            assert im.width == 1024
            assert im.height == 768
            assert im.bands == 3

        self.file_loader("jpegload", JPEG_FILE, jpeg_valid)
        self.save_load("%s.jpg", self.mono)
        self.save_load("%s.jpg", self.colour)

        self.buffer_loader("jpegload_buffer", JPEG_FILE, jpeg_valid)
        self.save_load_buffer("jpegsave_buffer", "jpegload_buffer",
                              self.colour, 80)

        # see if we have exif parsing: our test image has this field
        x = pyvips.Image.new_from_file(JPEG_FILE)
        if x.get_typeof("exif-ifd0-Orientation") != 0:
            # we need a copy of the image to set the new metadata on
            # otherwise we get caching problems

            # can set, save and load new orientation
            x = pyvips.Image.new_from_file(JPEG_FILE)
            x = x.copy()

            x.set("orientation", 2)

            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)

            x = pyvips.Image.new_from_file(filename)
            y = x.get("orientation")
            assert y == 2

            # can remove orientation, save, load again, orientation
            # has reset
            x.remove("orientation")

            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)

            x = pyvips.Image.new_from_file(filename)
            y = x.get("orientation")
            assert y == 1

            # autorotate load works
            x = pyvips.Image.new_from_file(JPEG_FILE)
            x = x.copy()

            x.set("orientation", 6)

            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)

            x1 = pyvips.Image.new_from_file(filename)
            x2 = pyvips.Image.new_from_file(filename, autorotate=True)
            assert x1.width == x2.height
            assert x1.height == x2.width

            # can set, save and reload ASCII string fields
            x = pyvips.Image.new_from_file(JPEG_FILE)
            x = x.copy()

            x.set_type(pyvips.GValue.gstr_type, "exif-ifd0-ImageDescription",
                       "hello world")

            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)

            x = pyvips.Image.new_from_file(filename)
            y = x.get("exif-ifd0-ImageDescription")
            # can't use == since the string will have an extra " (xx, yy, zz)"
            # format area at the end
            assert y.startswith("hello world")

            # can set, save and reload UTF16 string fields ... pyvips is
            # utf8, but it will be coded as utf16 and back for the XP* fields
            x = pyvips.Image.new_from_file(JPEG_FILE)
            x = x.copy()

            x.set_type(pyvips.GValue.gstr_type, "exif-ifd0-XPComment", u"йцук")

            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)

            x = pyvips.Image.new_from_file(filename)
            y = x.get("exif-ifd0-XPComment")
            # can't use == since the string will have an extra " (xx, yy, zz)"
            # format area at the end
            assert y.startswith(u"йцук")

            # can set/save/load UserComment, a tag which has the
            # encoding in the first 8 bytes ... though libexif only supports
            # ASCII for this
            x = pyvips.Image.new_from_file(JPEG_FILE)
            x = x.copy()

            x.set_type(pyvips.GValue.gstr_type, "exif-ifd2-UserComment",
                       "hello world")

            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)

            x = pyvips.Image.new_from_file(filename)
            y = x.get("exif-ifd2-UserComment")
            # can't use == since the string will have an extra " (xx, yy, zz)"
            # format area at the end
            assert y.startswith("hello world")
Пример #24
0
    def test_jpeg(self):
        def jpeg_valid(im):
            a = im(10, 10)
            assert_almost_equal_objects(a, [6, 5, 3])
            profile = im.get("icc-profile-data")
            assert len(profile) == 1352
            assert im.width == 1024
            assert im.height == 768
            assert im.bands == 3

        self.file_loader("jpegload", JPEG_FILE, jpeg_valid)
        self.save_load("%s.jpg", self.mono)
        self.save_load("%s.jpg", self.colour)

        self.buffer_loader("jpegload_buffer", JPEG_FILE, jpeg_valid)
        self.save_load_buffer("jpegsave_buffer", "jpegload_buffer",
                              self.colour, 80)

        # see if we have exif parsing: our test image has this field
        x = pyvips.Image.new_from_file(JPEG_FILE)
        if x.get_typeof("exif-ifd0-Orientation") != 0:
            # we need a copy of the image to set the new metadata on
            # otherwise we get caching problems

            # can set, save and load new orientation
            x = pyvips.Image.new_from_file(JPEG_FILE)
            x = x.copy()

            x.set("orientation", 2)

            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)

            x = pyvips.Image.new_from_file(filename)
            y = x.get("orientation")
            assert y == 2

            # can remove orientation, save, load again, orientation
            # has reset
            x.remove("orientation")

            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)

            x = pyvips.Image.new_from_file(filename)
            y = x.get("orientation")
            assert y == 1

            # autorotate load works
            x = pyvips.Image.new_from_file(JPEG_FILE)
            x = x.copy()

            x.set("orientation", 6)

            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)

            x1 = pyvips.Image.new_from_file(filename)
            x2 = pyvips.Image.new_from_file(filename, autorotate=True)
            assert x1.width == x2.height
            assert x1.height == x2.width

            # can set, save and reload ASCII string fields
            x = pyvips.Image.new_from_file(JPEG_FILE)
            x = x.copy()

            x.set_type(pyvips.GValue.gstr_type, 
                       "exif-ifd0-ImageDescription", "hello world")

            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)

            x = pyvips.Image.new_from_file(filename)
            y = x.get("exif-ifd0-ImageDescription")
            # can't use == since the string will have an extra " (xx, yy, zz)" 
            # format area at the end
            assert y.startswith("hello world")

            # can set, save and reload UTF16 string fields ... pyvips is 
            # utf8, but it will be coded as utf16 and back for the XP* fields
            x = pyvips.Image.new_from_file(JPEG_FILE)
            x = x.copy()

            x.set_type(pyvips.GValue.gstr_type, "exif-ifd0-XPComment", u"йцук")

            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)

            x = pyvips.Image.new_from_file(filename)
            y = x.get("exif-ifd0-XPComment")
            # can't use == since the string will have an extra " (xx, yy, zz)" 
            # format area at the end
            assert y.startswith(u"йцук")

            # can set/save/load UserComment, a tag which has the
            # encoding in the first 8 bytes ... though libexif only supports
            # ASCII for this
            x = pyvips.Image.new_from_file(JPEG_FILE)
            x = x.copy()

            x.set_type(pyvips.GValue.gstr_type, 
                       "exif-ifd2-UserComment", "hello world")

            filename = temp_filename(self.tempdir, '.jpg')
            x.write_to_file(filename)

            x = pyvips.Image.new_from_file(filename)
            y = x.get("exif-ifd2-UserComment")
            # can't use == since the string will have an extra " (xx, yy, zz)" 
            # format area at the end
            assert y.startswith("hello world")
Пример #25
0
    def test_tiff(self):
        def tiff_valid(im):
            a = im(10, 10)
            assert_almost_equal_objects(a, [38671.0, 33914.0, 26762.0])
            assert im.width == 290
            assert im.height == 442
            assert im.bands == 3

        self.file_loader("tiffload", TIF_FILE, tiff_valid)
        self.buffer_loader("tiffload_buffer", TIF_FILE, tiff_valid)
        if pyvips.at_least_libvips(8, 5):
            self.save_load_buffer("tiffsave_buffer",
                                  "tiffload_buffer",
                                  self.colour)
        self.save_load("%s.tif", self.mono)
        self.save_load("%s.tif", self.colour)
        self.save_load("%s.tif", self.cmyk)

        self.save_load("%s.tif", self.onebit)
        self.save_load_file(".tif", "[squash]", self.onebit, 0)
        self.save_load_file(".tif", "[miniswhite]", self.onebit, 0)
        self.save_load_file(".tif", "[squash,miniswhite]", self.onebit, 0)

        self.save_load_file(".tif",
                            "[profile={0}]".format(SRGB_FILE),
                            self.colour, 0)
        self.save_load_file(".tif", "[tile]", self.colour, 0)
        self.save_load_file(".tif", "[tile,pyramid]", self.colour, 0)
        self.save_load_file(".tif",
                            "[tile,pyramid,compression=jpeg]", self.colour, 80)
        self.save_load_file(".tif", "[bigtiff]", self.colour, 0)
        self.save_load_file(".tif", "[compression=jpeg]", self.colour, 80)
        self.save_load_file(".tif",
                            "[tile,tile-width=256]", self.colour, 10)

        filename = temp_filename(self.tempdir, '.tif')
        x = pyvips.Image.new_from_file(TIF_FILE)
        x = x.copy()
        x.set("orientation", 2)
        x.write_to_file(filename)
        x = pyvips.Image.new_from_file(filename)
        y = x.get("orientation")
        assert y == 2

        filename = temp_filename(self.tempdir, '.tif')
        x = pyvips.Image.new_from_file(TIF_FILE)
        x = x.copy()
        x.set("orientation", 2)
        x.write_to_file(filename)
        x = pyvips.Image.new_from_file(filename)
        y = x.get("orientation")
        assert y == 2
        x.remove("orientation")

        filename = temp_filename(self.tempdir, '.tif')
        x.write_to_file(filename)
        x = pyvips.Image.new_from_file(filename)
        y = x.get("orientation")
        assert y == 1

        filename = temp_filename(self.tempdir, '.tif')
        x = pyvips.Image.new_from_file(TIF_FILE)
        x = x.copy()
        x.set("orientation", 6)
        x.write_to_file(filename)
        x1 = pyvips.Image.new_from_file(filename)
        x2 = pyvips.Image.new_from_file(filename, autorotate=True)
        assert x1.width == x2.height
        assert x1.height == x2.width

        # OME support in 8.5
        x = pyvips.Image.new_from_file(OME_FILE)
        assert x.width == 439
        assert x.height == 167
        page_height = x.height

        x = pyvips.Image.new_from_file(OME_FILE, n=-1)
        assert x.width == 439
        assert x.height == page_height * 15

        x = pyvips.Image.new_from_file(OME_FILE, page=1, n=-1)
        assert x.width == 439
        assert x.height == page_height * 14

        x = pyvips.Image.new_from_file(OME_FILE, page=1, n=2)
        assert x.width == 439
        assert x.height == page_height * 2

        x = pyvips.Image.new_from_file(OME_FILE, n=-1)
        assert x(0, 166)[0] == 96
        assert x(0, 167)[0] == 0
        assert x(0, 168)[0] == 1

        filename = temp_filename(self.tempdir, '.tif')
        x.write_to_file(filename)

        x = pyvips.Image.new_from_file(filename, n=-1)
        assert x.width == 439
        assert x.height == page_height * 15
        assert x(0, 166)[0] == 96
        assert x(0, 167)[0] == 0
        assert x(0, 168)[0] == 1

        # pyr save to buffer added in 8.6
        x = pyvips.Image.new_from_file(TIF_FILE)
        buf = x.tiffsave_buffer(tile=True, pyramid=True)
        filename = temp_filename(self.tempdir, '.tif')
        x.tiffsave(filename, tile=True, pyramid=True)
        with open(filename, 'rb') as f:
            buf2 = f.read()
        assert len(buf) == len(buf2)

        a = pyvips.Image.new_from_buffer(buf, "", page=2)
        b = pyvips.Image.new_from_buffer(buf2, "", page=2)
        assert a.width == b.width
        assert a.height == b.height
        assert a.avg() == b.avg()

        # region-shrink added in 8.7
        x = pyvips.Image.new_from_file(TIF_FILE)
        buf = x.tiffsave_buffer(tile=True, pyramid=True, region_shrink="mean")
        buf = x.tiffsave_buffer(tile=True, pyramid=True, region_shrink="mode")
        buf = x.tiffsave_buffer(tile=True, pyramid=True, region_shrink="median")
Пример #26
0
    def test_dzsave(self):
        # dzsave is hard to test, there are so many options
        # test each option separately and hope they all function together
        # correctly

        # default deepzoom layout ... we must use png here, since we want to
        # test the overlap for equality
        filename = temp_filename(self.tempdir, '')
        self.colour.dzsave(filename, suffix=".png")

        # test horizontal overlap ... expect 256 step, overlap 1
        x = pyvips.Image.new_from_file(filename + "_files/10/0_0.png")
        assert x.width == 255
        y = pyvips.Image.new_from_file(filename + "_files/10/1_0.png")
        assert y.width == 256

        # the right two columns of x should equal the left two columns of y
        left = x.crop(x.width - 2, 0, 2, x.height)
        right = y.crop(0, 0, 2, y.height)
        assert (left - right).abs().max() == 0

        # test vertical overlap
        assert x.height == 255
        y = pyvips.Image.new_from_file(filename + "_files/10/0_1.png")
        assert y.height == 256

        # the bottom two rows of x should equal the top two rows of y
        top = x.crop(0, x.height - 2, x.width, 2)
        bottom = y.crop(0, 0, y.width, 2)
        assert (top - bottom).abs().max() == 0

        # there should be a bottom layer
        x = pyvips.Image.new_from_file(filename + "_files/0/0_0.png")
        assert x.width == 1
        assert x.height == 1

        # 10 should be the final layer
        assert not os.path.isdir(filename + "_files/11")

        # default google layout
        filename = temp_filename(self.tempdir, '')
        self.colour.dzsave(filename, layout="google")

        # test bottom-right tile ... default is 256x256 tiles, overlap 0
        x = pyvips.Image.new_from_file(filename + "/2/2/3.jpg")
        assert x.width == 256
        assert x.height == 256
        assert not os.path.exists(filename + "/2/2/4.jpg")
        assert not os.path.exists(filename + "/3")
        x = pyvips.Image.new_from_file(filename + "/blank.png")
        assert x.width == 256
        assert x.height == 256

        # google layout with overlap ... verify that we clip correctly

        # overlap 1, 510x510 pixels, 256 pixel tiles, should be exactly 2x2
        # tiles, though in fact the bottom and right edges will be white
        filename = temp_filename(self.tempdir, '')
        self.colour.crop(0, 0, 510, 510).dzsave(filename, layout="google",
                                                overlap=1, depth="one")

        x = pyvips.Image.new_from_file(filename + "/0/1/1.jpg")
        assert x.width == 256
        assert x.height == 256
        assert not os.path.exists(filename + "/0/2/2.jpg")

        # with 511x511, it'll fit exactly into 2x2 -- we we actually generate
        # 3x3, since we output the overlaps
        filename = temp_filename(self.tempdir, '')
        self.colour.crop(0, 0, 511, 511).dzsave(filename, layout="google",
                                                overlap=1, depth="one")

        x = pyvips.Image.new_from_file(filename + "/0/2/2.jpg")
        assert x.width == 256
        assert x.height == 256
        assert not os.path.exists(filename + "/0/3/3.jpg")

        # default zoomify layout
        filename = temp_filename(self.tempdir, '')
        self.colour.dzsave(filename, layout="zoomify")

        # 256x256 tiles, no overlap
        assert os.path.exists(filename + "/ImageProperties.xml")
        x = pyvips.Image.new_from_file(filename + "/TileGroup0/2-3-2.jpg")
        assert x.width == 256
        assert x.height == 256

        # test zip output
        filename = temp_filename(self.tempdir, '.zip')
        self.colour.dzsave(filename)
        assert os.path.exists(filename)
        assert not os.path.exists(filename + "_files")
        assert not os.path.exists(filename + ".dzi")

        # test compressed zip output
        filename2 = temp_filename(self.tempdir, '.zip')
        self.colour.dzsave(filename2, compression=-1)
        assert os.path.exists(filename2)
        assert os.path.getsize(filename2) < os.path.getsize(filename)

        # test suffix
        filename = temp_filename(self.tempdir, '')
        self.colour.dzsave(filename, suffix=".png")

        x = pyvips.Image.new_from_file(filename + "_files/10/0_0.png")
        assert x.width == 255

        # test overlap
        filename = temp_filename(self.tempdir, '')
        self.colour.dzsave(filename, overlap=200)

        y = pyvips.Image.new_from_file(filename + "_files/10/1_1.jpeg")
        assert y.width == 654

        # test tile-size
        filename = temp_filename(self.tempdir, '')
        self.colour.dzsave(filename, tile_size=512)

        y = pyvips.Image.new_from_file(filename + "_files/10/0_0.jpeg")
        assert y.width == 513
        assert y.height == 513

        # test save to memory buffer
        filename = temp_filename(self.tempdir, '.zip')
        base = os.path.basename(filename)
        root, ext = os.path.splitext(base)

        self.colour.dzsave(filename)
        with open(filename, 'rb') as f:
            buf1 = f.read()
        buf2 = self.colour.dzsave_buffer(basename=root)
        assert len(buf1) == len(buf2)

        # we can't test the bytes are exactly equal -- the timestamps will
        # be different

        # added in 8.7
        buf = self.colour.dzsave_buffer(region_shrink="mean")
        buf = self.colour.dzsave_buffer(region_shrink="mode")
        buf = self.colour.dzsave_buffer(region_shrink="median")
Пример #27
0
    def test_target_new_to_file(self):
        filename = temp_filename(self.tempdir, ".jpg")
        x = pyvips.Target.new_to_file(filename)

        assert x.filename() == filename
Пример #28
0
    def test_streamo_new_to_file(self):
        filename = temp_filename(self.tempdir, ".jpg")
        x = pyvips.Streamo.new_to_file(filename)

        assert x.filename() == filename
Пример #29
0
    def test_tiff(self):
        def tiff_valid(im):
            a = im(10, 10)
            assert_almost_equal_objects(a, [38671.0, 33914.0, 26762.0])
            assert im.width == 290
            assert im.height == 442
            assert im.bands == 3

        self.file_loader("tiffload", TIF_FILE, tiff_valid)
        self.buffer_loader("tiffload_buffer", TIF_FILE, tiff_valid)

        def tiff1_valid(im):
            a = im(127, 0)
            assert_almost_equal_objects(a, [0.0])
            a = im(128, 0)
            assert_almost_equal_objects(a, [255.0])
            assert im.width == 256
            assert im.height == 4
            assert im.bands == 1

        self.file_loader("tiffload", TIF1_FILE, tiff1_valid)

        def tiff2_valid(im):
            a = im(127, 0)
            assert_almost_equal_objects(a, [85.0])
            a = im(128, 0)
            assert_almost_equal_objects(a, [170.0])
            assert im.width == 256
            assert im.height == 4
            assert im.bands == 1

        self.file_loader("tiffload", TIF2_FILE, tiff2_valid)

        def tiff4_valid(im):
            a = im(127, 0)
            assert_almost_equal_objects(a, [119.0])
            a = im(128, 0)
            assert_almost_equal_objects(a, [136.0])
            assert im.width == 256
            assert im.height == 4
            assert im.bands == 1

        self.file_loader("tiffload", TIF4_FILE, tiff4_valid)

        self.save_load_buffer("tiffsave_buffer", "tiffload_buffer",
                              self.colour)
        self.save_load("%s.tif", self.mono)
        self.save_load("%s.tif", self.colour)
        self.save_load("%s.tif", self.cmyk)

        self.save_load("%s.tif", self.onebit)
        self.save_load_file(".tif", "[bitdepth=1]", self.onebit, 0)
        self.save_load_file(".tif", "[miniswhite]", self.onebit, 0)
        self.save_load_file(".tif", "[bitdepth=1,miniswhite]", self.onebit, 0)

        self.save_load_file(".tif", "[profile={0}]".format(SRGB_FILE),
                            self.colour, 0)
        self.save_load_file(".tif", "[tile]", self.colour, 0)
        self.save_load_file(".tif", "[tile,pyramid]", self.colour, 0)
        self.save_load_file(".tif", "[tile,pyramid,subifd]", self.colour, 0)
        self.save_load_file(".tif", "[tile,pyramid,compression=jpeg]",
                            self.colour, 80)
        self.save_load_file(".tif", "[tile,pyramid,subifd,compression=jpeg]",
                            self.colour, 80)
        self.save_load_file(".tif", "[bigtiff]", self.colour, 0)
        self.save_load_file(".tif", "[compression=jpeg]", self.colour, 80)
        self.save_load_file(".tif", "[tile,tile-width=256]", self.colour, 10)

        im = pyvips.Image.new_from_file(TIF2_FILE)
        self.save_load_file(".tif", "[bitdepth=2]", im, 0)
        im = pyvips.Image.new_from_file(TIF4_FILE)
        self.save_load_file(".tif", "[bitdepth=4]", im, 0)

        filename = temp_filename(self.tempdir, '.tif')
        x = pyvips.Image.new_from_file(TIF_FILE)
        x = x.copy()
        x.set("orientation", 2)
        x.write_to_file(filename)
        x = pyvips.Image.new_from_file(filename)
        y = x.get("orientation")
        assert y == 2

        filename = temp_filename(self.tempdir, '.tif')
        x = pyvips.Image.new_from_file(TIF_FILE)
        x = x.copy()
        x.set("orientation", 2)
        x.write_to_file(filename)
        x = pyvips.Image.new_from_file(filename)
        y = x.get("orientation")
        assert y == 2
        x = x.copy()
        x.remove("orientation")

        filename = temp_filename(self.tempdir, '.tif')
        x.write_to_file(filename)
        x = pyvips.Image.new_from_file(filename)
        y = x.get("orientation")
        assert y == 1

        filename = temp_filename(self.tempdir, '.tif')
        x = pyvips.Image.new_from_file(TIF_FILE)
        x = x.copy()
        x.set("orientation", 6)
        x.write_to_file(filename)
        x1 = pyvips.Image.new_from_file(filename)
        x2 = pyvips.Image.new_from_file(filename, autorotate=True)
        assert x1.width == x2.height
        assert x1.height == x2.width

        filename = temp_filename(self.tempdir, '.tif')
        x = pyvips.Image.new_from_file(TIF_FILE)
        x = x.copy()
        x.write_to_file(filename, xres=100, yres=200, resunit="cm")
        x1 = pyvips.Image.new_from_file(filename)
        assert x1.get("resolution-unit") == "cm"
        assert x1.xres == 100
        assert x1.yres == 200

        filename = temp_filename(self.tempdir, '.tif')
        x = pyvips.Image.new_from_file(TIF_FILE)
        x = x.copy()
        x.write_to_file(filename, xres=100, yres=200, resunit="inch")
        x1 = pyvips.Image.new_from_file(filename)
        assert x1.get("resolution-unit") == "in"
        assert x1.xres == 100
        assert x1.yres == 200

        # OME support in 8.5
        x = pyvips.Image.new_from_file(OME_FILE)
        assert x.width == 439
        assert x.height == 167
        page_height = x.height

        x = pyvips.Image.new_from_file(OME_FILE, n=-1)
        assert x.width == 439
        assert x.height == page_height * 15

        x = pyvips.Image.new_from_file(OME_FILE, page=1, n=-1)
        assert x.width == 439
        assert x.height == page_height * 14

        x = pyvips.Image.new_from_file(OME_FILE, page=1, n=2)
        assert x.width == 439
        assert x.height == page_height * 2

        x = pyvips.Image.new_from_file(OME_FILE, n=-1)
        assert x(0, 166)[0] == 96
        assert x(0, 167)[0] == 0
        assert x(0, 168)[0] == 1

        filename = temp_filename(self.tempdir, '.tif')
        x.write_to_file(filename)

        x = pyvips.Image.new_from_file(filename, n=-1)
        assert x.width == 439
        assert x.height == page_height * 15
        assert x(0, 166)[0] == 96
        assert x(0, 167)[0] == 0
        assert x(0, 168)[0] == 1

        # pyr save to buffer added in 8.6
        x = pyvips.Image.new_from_file(TIF_FILE)
        buf = x.tiffsave_buffer(tile=True, pyramid=True)
        filename = temp_filename(self.tempdir, '.tif')
        x.tiffsave(filename, tile=True, pyramid=True)
        with open(filename, 'rb') as f:
            buf2 = f.read()
        assert len(buf) == len(buf2)

        a = pyvips.Image.new_from_buffer(buf, "", page=2)
        b = pyvips.Image.new_from_buffer(buf2, "", page=2)
        assert a.width == b.width
        assert a.height == b.height
        assert a.avg() == b.avg()

        # just 0/255 in each band, shrink with mode and all pixels should be 0
        # or 255 in layer 1
        x = pyvips.Image.new_from_file(TIF_FILE) > 128
        for shrink in ["mode", "median", "max", "min"]:
            buf = x.tiffsave_buffer(pyramid=True, region_shrink=shrink)
            y = pyvips.Image.new_from_buffer(buf, "", page=1)
            z = y.hist_find(band=0)
            assert z(0, 0)[0] + z(255, 0)[0] == y.width * y.height