comparison tests/test_pixmap.py @ 1:1d09e1dec1d9 upstream

ADD: PyMuPDF v1.26.4: the original sdist. It does not yet contain MuPDF. This normally will be downloaded when building PyMuPDF.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:37:51 +0200
parents
children a6bc019ac0b2
comparison
equal deleted inserted replaced
-1:000000000000 1:1d09e1dec1d9
1 """
2 Pixmap tests
3 * make pixmap of a page and assert bbox size
4 * make pixmap from a PDF xref and compare with extracted image
5 * pixmap from file and from binary image and compare
6 """
7
8 import pymupdf
9 import gentle_compare
10
11 import os
12 import platform
13 import subprocess
14 import sys
15 import tempfile
16 import pytest
17 import textwrap
18 import time
19
20
21 scriptdir = os.path.abspath(os.path.dirname(__file__))
22 epub = os.path.join(scriptdir, "resources", "Bezier.epub")
23 pdf = os.path.join(scriptdir, "resources", "001003ED.pdf")
24 imgfile = os.path.join(scriptdir, "resources", "nur-ruhig.jpg")
25
26
27 def test_pagepixmap():
28 # pixmap from an EPUB page
29 doc = pymupdf.open(epub)
30 page = doc[0]
31 pix = page.get_pixmap()
32 assert pix.irect == page.rect.irect
33 pix = page.get_pixmap(alpha=True)
34 assert pix.alpha
35 assert pix.n == pix.colorspace.n + pix.alpha
36
37
38 def test_pdfpixmap():
39 # pixmap from xref in a PDF
40 doc = pymupdf.open(pdf)
41 # take first image item of first page
42 img = doc.get_page_images(0)[0]
43 # make pixmap of it
44 pix = pymupdf.Pixmap(doc, img[0])
45 # assert pixmap properties
46 assert pix.width == img[2]
47 assert pix.height == img[3]
48 # extract image and compare metadata
49 extractimg = doc.extract_image(img[0])
50 assert extractimg["width"] == pix.width
51 assert extractimg["height"] == pix.height
52
53
54 def test_filepixmap():
55 # pixmaps from file and from stream
56 # should lead to same result
57 pix1 = pymupdf.Pixmap(imgfile)
58 stream = open(imgfile, "rb").read()
59 pix2 = pymupdf.Pixmap(stream)
60 assert repr(pix1) == repr(pix2)
61 assert pix1.digest == pix2.digest
62
63
64 def test_pilsave():
65 # pixmaps from file then save to pillow image
66 # make pixmap from this and confirm equality
67 try:
68 pix1 = pymupdf.Pixmap(imgfile)
69 stream = pix1.pil_tobytes("JPEG")
70 pix2 = pymupdf.Pixmap(stream)
71 assert repr(pix1) == repr(pix2)
72 except ModuleNotFoundError:
73 assert platform.system() == 'Windows' and sys.maxsize == 2**31 - 1
74
75
76 def test_save(tmpdir):
77 # pixmaps from file then save to image
78 # make pixmap from this and confirm equality
79 pix1 = pymupdf.Pixmap(imgfile)
80 outfile = os.path.join(tmpdir, "foo.png")
81 pix1.save(outfile, output="png")
82 # read it back
83 pix2 = pymupdf.Pixmap(outfile)
84 assert repr(pix1) == repr(pix2)
85
86
87 def test_setalpha():
88 # pixmap from JPEG file, then add an alpha channel
89 # with 30% transparency
90 pix1 = pymupdf.Pixmap(imgfile)
91 opa = int(255 * 0.3) # corresponding to 30% transparency
92 alphas = [opa] * (pix1.width * pix1.height)
93 alphas = bytearray(alphas)
94 pix2 = pymupdf.Pixmap(pix1, 1) # add alpha channel
95 pix2.set_alpha(alphas) # make image 30% transparent
96 samples = pix2.samples # copy of samples
97 # confirm correct the alpha bytes
98 t = bytearray([samples[i] for i in range(3, len(samples), 4)])
99 assert t == alphas
100
101 def test_color_count():
102 '''
103 This is known to fail if MuPDF is built without PyMuPDF's custom config.h,
104 e.g. in Linux system installs.
105 '''
106 pm = pymupdf.Pixmap(imgfile)
107 assert pm.color_count() == 40624
108
109 def test_memoryview():
110 pm = pymupdf.Pixmap(imgfile)
111 samples = pm.samples_mv
112 assert isinstance( samples, memoryview)
113 print( f'samples={samples} samples.itemsize={samples.itemsize} samples.nbytes={samples.nbytes} samples.ndim={samples.ndim} samples.shape={samples.shape} samples.strides={samples.strides}')
114 assert samples.itemsize == 1
115 assert samples.nbytes == 659817
116 assert samples.ndim == 1
117 assert samples.shape == (659817,)
118 assert samples.strides == (1,)
119
120 color = pm.pixel( 100, 100)
121 print( f'color={color}')
122 assert color == (83, 66, 40)
123
124 def test_samples_ptr():
125 pm = pymupdf.Pixmap(imgfile)
126 samples = pm.samples_ptr
127 print( f'samples={samples}')
128 assert isinstance( samples, int)
129
130 def test_2369():
131
132 width, height = 13, 37
133 image = pymupdf.Pixmap(pymupdf.csGRAY, width, height, b"\x00" * (width * height), False)
134
135 with pymupdf.Document(stream=image.tobytes(output="pam"), filetype="pam") as doc:
136 test_pdf_bytes = doc.convert_to_pdf()
137
138 with pymupdf.Document(stream=test_pdf_bytes) as doc:
139 page = doc[0]
140 img_xref = page.get_images()[0][0]
141 img = doc.extract_image(img_xref)
142 img_bytes = img["image"]
143 pymupdf.Pixmap(img_bytes)
144
145 def test_page_idx_int():
146 doc = pymupdf.open(pdf)
147 with pytest.raises(AssertionError):
148 doc["0"]
149 assert doc[0]
150 assert doc[(0,0)]
151
152 def test_fz_write_pixmap_as_jpeg():
153 width, height = 13, 37
154 image = pymupdf.Pixmap(pymupdf.csGRAY, width, height, b"\x00" * (width * height), False)
155
156 with pymupdf.Document(stream=image.tobytes(output="jpeg"), filetype="jpeg") as doc:
157 test_pdf_bytes = doc.convert_to_pdf()
158
159 def test_3020():
160 pm = pymupdf.Pixmap(imgfile)
161 pm2 = pymupdf.Pixmap(pm, 20, 30, None)
162 pm3 = pymupdf.Pixmap(pymupdf.csGRAY, pm)
163 pm4 = pymupdf.Pixmap(pm, pm3)
164
165 def test_3050():
166 '''
167 This is known to fail if MuPDF is built without it's default third-party
168 libraries, e.g. in Linux system installs.
169 '''
170 path = os.path.normpath(f'{__file__}/../../tests/resources/001003ED.pdf')
171 with pymupdf.open(path) as pdf_file:
172 page_no = 0
173 page = pdf_file[page_no]
174 zoom_x = 4.0
175 zoom_y = 4.0
176 matrix = pymupdf.Matrix(zoom_x, zoom_y)
177 pix = page.get_pixmap(matrix=matrix)
178 path_out = os.path.normpath(f'{__file__}/../../tests/test_3050_out.png')
179 pix.save(path_out)
180 print(f'{pix.width=} {pix.height=}')
181 def product(x, y):
182 for yy in y:
183 for xx in x:
184 yield (xx, yy)
185 n = 0
186 # We use a small subset of the image because non-optimised rebase gets
187 # very slow.
188 for pos in product(range(100), range(100)):
189 if sum(pix.pixel(pos[0], pos[1])) >= 600:
190 n += 1
191 pix.set_pixel(pos[0], pos[1], (255, 255, 255))
192 path_out2 = os.path.normpath(f'{__file__}/../../tests/test_3050_out2.png')
193 pix.save(path_out2)
194 path_expected = os.path.normpath(f'{__file__}/../../tests/resources/test_3050_expected.png')
195 rms = gentle_compare.pixmaps_rms(path_expected, path_out2)
196 print(f'{rms=}')
197 if pymupdf.mupdf_version_tuple < (1, 26):
198 # Slight differences in rendering from fix for mupdf bug 708274.
199 assert rms < 0.2
200 else:
201 assert rms == 0
202 wt = pymupdf.TOOLS.mupdf_warnings()
203 if pymupdf.mupdf_version_tuple >= (1, 26, 0):
204 assert wt == 'bogus font ascent/descent values (0 / 0)\nPDF stream Length incorrect'
205 else:
206 assert wt == 'PDF stream Length incorrect'
207
208 def test_3058():
209 doc = pymupdf.Document(os.path.abspath(f'{__file__}/../../tests/resources/test_3058.pdf'))
210 images = doc[0].get_images(full=True)
211 pix = pymupdf.Pixmap(doc, 17)
212
213 # First bug was that `pix.colorspace` was DeviceRGB.
214 assert str(pix.colorspace) == 'Colorspace(CS_CMYK) - DeviceCMYK'
215
216 pix = pymupdf.Pixmap(pymupdf.csRGB, pix)
217 assert str(pix.colorspace) == 'Colorspace(CS_RGB) - DeviceRGB'
218
219 # Second bug was that the image was converted to RGB via greyscale proofing
220 # color space, so image contained only shades of grey. This compressed
221 # easily to a .png file, so we crudely check the bug is fixed by looking at
222 # size of .png file.
223 path = os.path.abspath(f'{__file__}/../../tests/test_3058_out.png')
224 pix.save(path)
225 s = os.path.getsize(path)
226 assert 1800000 < s < 2600000, f'Unexpected size of {path}: {s}'
227
228 def test_3072():
229 path = os.path.abspath(f'{__file__}/../../tests/resources/test_3072.pdf')
230 out = os.path.abspath(f'{__file__}/../../tests')
231
232 doc = pymupdf.open(path)
233 page_48 = doc[0]
234 bbox = [147, 300, 447, 699]
235 rect = pymupdf.Rect(*bbox)
236 zoom = pymupdf.Matrix(3, 3)
237 pix = page_48.get_pixmap(clip=rect, matrix=zoom)
238 image_save_path = f'{out}/1.jpg'
239 pix.save(image_save_path, jpg_quality=95)
240
241 doc = pymupdf.open(path)
242 page_49 = doc[1]
243 bbox = [147, 543, 447, 768]
244 rect = pymupdf.Rect(*bbox)
245 zoom = pymupdf.Matrix(3, 3)
246 pix = page_49.get_pixmap(clip=rect, matrix=zoom)
247 image_save_path = f'{out}/2.jpg'
248 pix.save(image_save_path, jpg_quality=95)
249 rebase = hasattr(pymupdf, 'mupdf')
250 if rebase:
251 wt = pymupdf.TOOLS.mupdf_warnings()
252 assert wt == (
253 "syntax error: cannot find ExtGState resource 'BlendMode0'\n"
254 "encountered syntax errors; page may not be correct\n"
255 "syntax error: cannot find ExtGState resource 'BlendMode0'\n"
256 "encountered syntax errors; page may not be correct"
257 )
258
259 def test_3134():
260 doc = pymupdf.Document()
261 page = doc.new_page()
262 page.get_pixmap(clip=pymupdf.Rect(0, 0, 100, 100)).save("test_3134_rect.jpg")
263 page.get_pixmap(clip=pymupdf.IRect(0, 0, 100, 100)).save("test_3134_irect.jpg")
264 stat_rect = os.stat('test_3134_rect.jpg')
265 stat_irect = os.stat('test_3134_irect.jpg')
266 print(f' {stat_rect=}')
267 print(f'{stat_irect=}')
268 assert stat_rect.st_size == stat_irect.st_size
269
270 def test_3177():
271 path = os.path.abspath(f'{__file__}/../../tests/resources/img-transparent.png')
272 pixmap = pymupdf.Pixmap(path)
273 pixmap2 = pymupdf.Pixmap(None, pixmap)
274
275
276 def test_3493():
277 '''
278 If python3-gi is installed, we check fix for #3493, where importing gi
279 would load an older version of libjpeg than is used in MuPDF, and break
280 MuPDF.
281
282 This test is excluded by default in sysinstall tests, because running
283 commands in a new venv does not seem to pick up pymupdf as expected.
284 '''
285 if platform.system() != 'Linux':
286 print(f'Not running because not Linux: {platform.system()=}')
287 return
288
289 import subprocess
290
291 root = os.path.abspath(f'{__file__}/../..')
292 in_path = f'{root}/tests/resources/test_3493.epub'
293
294 def run(command, check=1, stdout=None):
295 print(f'Running with {check=}: {command}')
296 return subprocess.run(command, shell=1, check=check, stdout=stdout, text=1)
297
298 def run_code(code, code_path, *, check=True, venv=None, venv_args='', pythonpath=None, stdout=None):
299 code = textwrap.dedent(code)
300 with open(code_path, 'w') as f:
301 f.write(code)
302 prefix = f'PYTHONPATH={pythonpath} ' if pythonpath else ''
303 if venv:
304 # Have seen this fail on Github in a curious way:
305 #
306 # Running: /tmp/tmp.fBeKNLJQKk/venv/bin/python -m venv --system-site-packages /project/tests/resources/test_3493_venv
307 # Error: [Errno 2] No such file or directory: '/project/tests/resources/test_3493_venv/bin/python'
308 #
309 r = run(f'{sys.executable} -m venv {venv_args} {venv}', check=check)
310 if r.returncode:
311 return r
312 r = run(f'. {venv}/bin/activate && {prefix}python {code_path}', check=check, stdout=stdout)
313 else:
314 r = run(f'{prefix}{sys.executable} {code_path}', check=check, stdout=stdout)
315 return r
316
317 # Find location of system install of `gi`.
318 r = run_code(
319 '''
320 from gi.repository import GdkPixbuf
321 import gi
322 print(gi.__file__)
323 '''
324 ,
325 f'{root}/tests/resources/test_3493_gi.py',
326 check=0,
327 venv=f'{root}/tests/resources/test_3493_venv',
328 venv_args='--system-site-packages',
329 stdout=subprocess.PIPE,
330 )
331 if r.returncode:
332 print(f'test_3493(): Not running test because --system-site-packages venv cannot import gi.')
333 return
334 gi = r.stdout.strip()
335 gi_pythonpath = os.path.abspath(f'{gi}/../..')
336
337 def do(gi):
338 # Run code that will import gi and pymupdf in different orders, and
339 # return contents of generated .png file as a bytes.
340 out = f'{root}/tests/resources/test_3493_{gi}.png'
341 run_code(
342 f'''
343 if {gi}==0:
344 import pymupdf
345 elif {gi}==1:
346 from gi.repository import GdkPixbuf
347 import pymupdf
348 elif {gi}==2:
349 import pymupdf
350 from gi.repository import GdkPixbuf
351 else:
352 assert 0
353 document = pymupdf.Document('{in_path}')
354 page = document[0]
355 print(f'{gi=}: saving to: {out}')
356 page.get_pixmap().save('{out}')
357 '''
358 ,
359 os.path.abspath(f'{root}/tests/resources/test_3493_{gi}.py'),
360 pythonpath=gi_pythonpath,
361 )
362 with open(out, 'rb') as f:
363 return f.read()
364
365 out0 = do(0)
366 out1 = do(1)
367 out2 = do(2)
368 print(f'{len(out0)=} {len(out1)=} {len(out2)=}.')
369 assert out1 == out0
370 assert out2 == out0
371
372
373 def test_3848():
374 if os.environ.get('PYMUPDF_RUNNING_ON_VALGRIND') == '1':
375 # Takes 40m on Github.
376 print(f'test_3848(): not running on valgrind because very slow.', flush=1)
377 return
378 if platform.python_implementation() == 'GraalVM':
379 print(f'test_3848(): Not running because slow on GraalVM.')
380 return
381 path = os.path.normpath(f'{__file__}/../../tests/resources/test_3848.pdf')
382 with pymupdf.open(path) as document:
383 for i in range(len(document)):
384 page = document.load_page(i)
385 print(f'{page=}.')
386 for annot in page.get_drawings():
387 if page.get_textbox(annot['rect']):
388 rect = annot['rect']
389 pixmap = page.get_pixmap(clip=rect)
390 color_bytes = pixmap.color_topusage()
391
392
393 def test_3994():
394 path = os.path.normpath(f'{__file__}/../../tests/resources/test_3994.pdf')
395 with pymupdf.open(path) as document:
396 page = document[0]
397 txt_blocks = [blk for blk in page.get_text('dict')['blocks'] if blk['type']==0]
398 for blk in txt_blocks:
399 pix = page.get_pixmap(clip=pymupdf.Rect([int(v) for v in blk['bbox']]), colorspace=pymupdf.csRGB, alpha=False)
400 percent, color = pix.color_topusage()
401 wt = pymupdf.TOOLS.mupdf_warnings()
402 assert wt == 'premature end of data in flate filter\n... repeated 2 times...'
403
404
405 def test_3448():
406 path = os.path.normpath(f'{__file__}/../../tests/resources/test_3448.pdf')
407 with pymupdf.open(path) as document:
408 page = document[0]
409 pixmap = page.get_pixmap(alpha=False, dpi=150)
410 path_out = f'{path}.png'
411 pixmap.save(path_out)
412 print(f'Have written to: {path_out}')
413 path_expected = os.path.normpath(f'{__file__}/../../tests/resources/test_3448.pdf-expected.png')
414 pixmap_expected = pymupdf.Pixmap(path_expected)
415 rms = gentle_compare.pixmaps_rms(pixmap, pixmap_expected)
416 diff = gentle_compare.pixmaps_diff(pixmap_expected, pixmap)
417 path_diff = os.path.normpath(f'{__file__}/../../tests/test_3448-diff.png')
418 diff.save(path_diff)
419 print(f'{rms=}')
420 if pymupdf.mupdf_version_tuple < (1, 25, 5):
421 # Prior to fix for mupdf bug 708274.
422 assert 1 < rms < 2
423 else:
424 assert rms == 0
425
426
427 def test_3854():
428 path = os.path.normpath(f'{__file__}/../../tests/resources/test_3854.pdf')
429 with pymupdf.open(path) as document:
430 page = document[0]
431 pixmap = page.get_pixmap()
432 pixmap.save(os.path.normpath(f'{__file__}/../../tests/test_3854_out.png'))
433
434 # 2024-11-29: this is the incorrect expected output.
435 path_expected_png = os.path.normpath(f'{__file__}/../../tests/resources/test_3854_expected.png')
436 pixmap_expected = pymupdf.Pixmap(path_expected_png)
437 pixmap_diff = gentle_compare.pixmaps_diff(pixmap_expected, pixmap)
438 path_diff = os.path.normpath(f'{__file__}/../../tests/resources/test_3854_diff.png')
439 pixmap_diff.save(path_diff)
440 rms = gentle_compare.pixmaps_rms(pixmap, pixmap_expected)
441 print(f'{rms=}.')
442 if os.environ.get('PYMUPDF_SYSINSTALL_TEST') == '1':
443 # MuPDF using external third-party libs gives slightly different
444 # behaviour.
445 assert rms < 2
446 elif pymupdf.mupdf_version_tuple < (1, 25, 5):
447 # # Prior to fix for mupdf bug 708274.
448 assert 0.5 < rms < 2
449 else:
450 assert rms == 0
451
452
453 def test_4155():
454 path = os.path.normpath(f'{__file__}/../../tests/resources/test_3854.pdf')
455 with pymupdf.open(path) as document:
456 page = document[0]
457 pixmap = page.get_pixmap()
458 mv = pixmap.samples_mv
459 mvb1 = mv.tobytes()
460 del page
461 del pixmap
462 try:
463 mvb2 = mv.tobytes()
464 except ValueError as e:
465 print(f'Received exception: {e}')
466 assert 'operation forbidden on released memoryview object' in str(e)
467 else:
468 assert 0, f'Did not receive expected exception when using defunct memoryview.'
469
470
471 def test_4336():
472 if 0:
473 # Compare with last classic release.
474 import pickle
475 path_out = os.path.normpath(f'{__file__}/../../tests/resources/test_4336_cc')
476 code = textwrap.dedent(f'''
477 import fitz
478 import os
479 import time
480 import pickle
481
482 path = os.path.normpath(f'{__file__}/../../tests/resources/nur-ruhig.jpg')
483 pixmap = fitz.Pixmap(path)
484 t = time.time()
485 for i in range(10):
486 cc = pixmap.color_count()
487 t = time.time() - t
488 print(f'test_4336(): {{t=}}')
489 with open({path_out!r}, 'wb') as f:
490 pickle.dump(cc, f)
491 ''')
492 path_code = os.path.normpath(f'{__file__}/../../tests/resources/test_4336.py')
493 with open(path_code, 'w') as f:
494 f.write(code)
495 venv = os.path.normpath(f'{__file__}/../../tests/resources/test_4336_venv')
496 command = f'{sys.executable} -m venv {venv}'
497 command += f' && . {venv}/bin/activate'
498 command += f' && pip install --force-reinstall pymupdf==1.23.8'
499 command += f' && python {path_code}'
500 print(f'Running: {command}', flush=1)
501 subprocess.run(command, shell=1, check=1)
502 with open(path_out, 'rb') as f:
503 cc_old = pickle.load(f)
504 else:
505 cc_old = None
506 path = os.path.normpath(f'{__file__}/../../tests/resources/nur-ruhig.jpg')
507 pixmap = pymupdf.Pixmap(path)
508 t = time.time()
509 for i in range(10):
510 cc = pixmap.color_count()
511 t = time.time() - t
512 print(f'test_4336(): {t=}')
513
514 if cc_old:
515 assert cc == cc_old
516
517
518 def test_4435():
519 print(f'{pymupdf.version=}')
520 path = os.path.normpath(f'{__file__}/../../tests/resources/test_4435.pdf')
521 with pymupdf.open(path) as document:
522 page = document[2]
523 print(f'Calling page.get_pixmap().', flush=1)
524 pixmap = page.get_pixmap(alpha=False, dpi=120)
525 print(f'Called page.get_pixmap().', flush=1)
526 wt = pymupdf.TOOLS.mupdf_warnings()
527 assert wt == 'bogus font ascent/descent values (0 / 0)\n... repeated 9 times...'
528
529
530 def test_4423():
531 path = os.path.normpath(f'{__file__}/../../tests/resources/test_4423.pdf')
532 with pymupdf.open(path) as document:
533 path2 = f'{path}.pdf'
534 ee = None
535 try:
536 document.save(
537 path2,
538 garbage=4,
539 expand=1,
540 deflate=True,
541 pretty=True,
542 no_new_id=True,
543 )
544 except Exception as e:
545 print(f'Exception: {e}')
546 ee = e
547
548 if (1, 25, 5) <= pymupdf.mupdf_version_tuple < (1, 26):
549 assert ee, f'Did not receive the expected exception.'
550 wt = pymupdf.TOOLS.mupdf_warnings()
551 assert wt == 'dropping unclosed output'
552 else:
553 assert not ee, f'Received unexpected exception: {e}'
554 wt = pymupdf.TOOLS.mupdf_warnings()
555 assert wt == 'format error: cannot find object in xref (56 0 R)\nformat error: cannot find object in xref (68 0 R)'
556
557
558 def test_4445():
559 print()
560 # Test case is large so we download it instead of having it in PyMuPDF
561 # git. We put it in `cache/` directory do it is not removed by `git clean`
562 # (unless `-d` is specified).
563 import util
564 path = util.download(
565 'https://github.com/user-attachments/files/19738242/ss.pdf',
566 'test_4445.pdf',
567 size=2671185,
568 )
569 with pymupdf.open(path) as document:
570 page = document[0]
571 pixmap = page.get_pixmap()
572 print(f'{pixmap.width=}')
573 print(f'{pixmap.height=}')
574 if pymupdf.mupdf_version_tuple >= (1, 26):
575 assert (pixmap.width, pixmap.height) == (792, 612)
576 else:
577 assert (pixmap.width, pixmap.height) == (612, 792)
578 if 0:
579 path_pixmap = f'{path}.png'
580 pixmap.save(path_pixmap)
581 print(f'Have created {path_pixmap=}')
582 wt = pymupdf.TOOLS.mupdf_warnings()
583 print(f'{wt=}')
584 assert wt == 'broken xref subsection, proceeding anyway.\nTrailer Size is off-by-one. Ignoring.'
585
586
587 def test_3806():
588 print()
589 print(f'{pymupdf.mupdf_version=}')
590 path = os.path.normpath(f'{__file__}/../../tests/resources/test_3806.pdf')
591 path_png_expected = os.path.normpath(f'{__file__}/../../tests/resources/test_3806-expected.png')
592 path_png = os.path.normpath(f'{__file__}/../../tests/test_3806.png')
593
594 with pymupdf.open(path) as document:
595 pixmap = document[0].get_pixmap()
596 pixmap.save(path_png)
597 rms = gentle_compare.pixmaps_rms(path_png_expected, pixmap)
598 print(f'{rms=}')
599 if pymupdf.mupdf_version_tuple >= (1, 26, 6):
600 assert rms < 0.1
601 else:
602 assert rms > 50
603
604
605 def test_4388():
606 print()
607 path_BOZ1 = os.path.normpath(f'{__file__}/../../tests/resources/test_4388_BOZ1.pdf')
608 path_BUL1 = os.path.normpath(f'{__file__}/../../tests/resources/test_4388_BUL1.pdf')
609 path_correct = os.path.normpath(f'{__file__}/../../tests/resources/test_4388_BUL1.pdf.correct.png')
610 path_test = os.path.normpath(f'{__file__}/../../tests/resources/test_4388_BUL1.pdf.test.png')
611
612 with pymupdf.open(path_BUL1) as bul:
613 pixmap_correct = bul.load_page(0).get_pixmap()
614 pixmap_correct.save(path_correct)
615
616 pymupdf.TOOLS.store_shrink(100)
617
618 with pymupdf.open(path_BOZ1) as boz:
619 boz.load_page(0).get_pixmap()
620
621 with pymupdf.open(path_BUL1) as bul:
622 pixmap_test = bul.load_page(0).get_pixmap()
623 pixmap_test.save(path_test)
624
625 rms = gentle_compare.pixmaps_rms(pixmap_correct, pixmap_test)
626 print(f'{rms=}')
627 if pymupdf.mupdf_version_tuple >= (1, 26, 6):
628 assert rms == 0
629 else:
630 assert rms >= 10