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
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
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
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)
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
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)
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
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)
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)
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
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)
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
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
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
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
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")
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
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")
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")
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")
def test_target_new_to_file(self): filename = temp_filename(self.tempdir, ".jpg") x = pyvips.Target.new_to_file(filename) assert x.filename() == filename
def test_streamo_new_to_file(self): filename = temp_filename(self.tempdir, ".jpg") x = pyvips.Streamo.new_to_file(filename) assert x.filename() == filename
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