The mid point of zero and an odd number is not an integer. So 50% gray, with integer IM, cannot be exactly 50%.
If we blur black and white together, we get a gray. But what gray?
To experiment, we draw three squares. The middle one has alternating black and white lines. Then we blur this, and place it on the left. Then we again blur the black and white lines, but this time in linear RGB space, and place it on the right.
%IMG7%magick ^ xc:White xc:Black -append +repage ^ +write mpr:TILE +delete ^ -size 200x200 ^ tile:mpr:TILE ^ -virtual-pixel Tile ^ ( -clone 0 -blur 0x4 ) ^ ( -clone 0 -colorspace RGB -blur 0x4 -colorspace sRGB ) ^ -swap 0,1 ^ -precision 8 ^ -format "%%[fx:mean]\n" ^ ( -clone 0 ^ -gravity center -crop 2x2+0+0 +write txt: ^ +delete )^ ( -clone 0 +write info: +delete )^ ( -clone 1 +write info: +delete )^ ( -clone 2 +write info: +delete )^ +append +repage ^ fpc_blurbw.png |
# ImageMagick pixel enumeration: 2,2,0,65535,srgb 0,0: (32767,32767,32767) #7FFF7FFF7FFF srgb(49.999076%,49.999076%,49.999076%) 1,0: (32767,32767,32767) #7FFF7FFF7FFF srgb(49.999076%,49.999076%,49.999076%) 0,1: (32768,32768,32768) #800080008000 srgb(50.000924%,50.000924%,50.000924%) 1,1: (32768,32768,32768) #800080008000 srgb(50.000924%,50.000924%,50.000924%) 0.5 0.5 0.735357
The middle square alternates black and white lines.
The left-hand square blurs the black and white lines. This results in lines that alternate between 49.9992% and 50.0008%. The overall average is 50%.
The right-hand square linearises the black and white lines, blurs this, then non-linearises the result. The overall gray is now 73.536%, which more accurately represents the visual average.
50% of 255 is 127.5, 50% of 65535 is 32767.5, and so on. These numbers cannot be represented with integer IM. This has some consequences:
100% / 2 == 50%
But:
50% + 50% != 100%
For example:
%IMG7%magick xc:gray(50%%) ( +clone ) -compose Plus -composite txt: %IMG7%magick xc:gray(50%%) ( +clone ) -evaluate-sequence Add txt: %IMG7%magick %PREC% xc:Black -evaluate Add 50%% -evaluate AddModulus 50%% txt:
# ImageMagick pixel enumeration: 1,1,0,65535,gray 0,0: (65535) #FFFFFFFFFFFF gray(255) # ImageMagick pixel enumeration: 1,1,0,65535,gray 0,0: (65535) #FFFFFFFFFFFF gray(255) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (0,0,0) #000000000000 black
We can generate a 50% value from a large number of methods. See the script testHalf.bat.
call %PICTBAT%testHalf . half_q16.lis
Version: ImageMagick 7.1.0-42 Q16-HDRI x64 396d87c:20220709 https://imagemagick.org Copyright: (C) 1999 ImageMagick Studio LLC License: https://imagemagick.org/script/license.php Features: Cipher DPC HDRI OpenCL Delegates (built-in): bzlib cairo freetype gslib heic jng jp2 jpeg jxl lcms lqr lzma openexr pangocairo png ps raqm raw rsvg tiff webp xml zip zlib Compiler: Visual Studio 2022 (193231332) With Q16i and Q32f, these give #8000. # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50.0007629510948%,50.0007629510948%,50.0007629510948%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50.0007629510948%,50.0007629510948%,50.0007629510948%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50.0007629510948%,50.0007629510948%,50.0007629510948%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) With Q16i and Q32f, these give #7fff: # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32767,32767,32767) #7FFF7FFF7FFF srgb(49.9992370489052%,49.9992370489052%,49.9992370489052%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32767,32767,32767) #7FFF7FFF7FFF srgb(49.9992370489052%,49.9992370489052%,49.9992370489052%) # ImageMagick pixel enumeration: 1,1,0,65535,gray 0,0: (32768) #800080008000 gray(50%) With Q16i, these give #7fff, but with Q32f they give #8000: # ImageMagick pixel enumeration: 1,1,0,65535,gray 0,0: (32768) #800080008000 gray(50%) # ImageMagick pixel enumeration: 1,1,0,65535,srgb 0,0: (32768,32768,32768) #800080008000 srgb(50%,50%,50%) These are arithmetically horrible in all Q: # ImageMagick pixel enumeration: 1,1,0,65535,gray 0,0: (32639) #7F7F7F7F7F7F gray(127)
call %PICTBAT%testHalf %IM7DEV% half_dev.lis
Version: ImageMagick 7.1.0-20 Q32-HDRI x86_64 2021-12-29 https://imagemagick.org Copyright: (C) 1999-2021 ImageMagick Studio LLC License: https://imagemagick.org/script/license.php Features: Cipher DPC HDRI Modules OpenMP(4.5) Delegates (built-in): bzlib cairo fontconfig fpx freetype jbig jng jpeg lcms ltdl lzma pangocairo png raqm rsvg tiff webp wmf x xml zip zlib Compiler: gcc (11.2) With Q16i and Q32f, these give #8000. # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #7FFFFFFF7FFFFFFF7FFFFFFF srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) With Q16i and Q32f, these give #7fff: # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #7FFFFFFF7FFFFFFF7FFFFFFF srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #7FFFFFFF7FFFFFFF7FFFFFFF srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,gray 0,0: (2147483648.5) #800000008000000080000000 gray(50.0000000116415%) With Q16i, these give #7fff, but with Q32f they give #8000: # ImageMagick pixel enumeration: 1,1,4294967295,gray 0,0: (2147483648.5) #800000008000000080000000 gray(50.0000000116415%) # ImageMagick pixel enumeration: 1,1,4294967295,srgb 0,0: (2147483648.5,2147483648.5,2147483648.5) #800000008000000080000000 srgb(50.0000000116415%,50.0000000116415%,50.0000000116415%) These are arithmetically horrible in all Q: # ImageMagick pixel enumeration: 1,1,4294967295,gray 0,0: (2139062144.49804) #7F7F7F7F7F7F7F7F7F7F7F7F gray(127.000000059372)
For convenience, .bat scripts are also available in a single zip file. See Zipped BAT files.
@rem @rem Updated: @rem 27-August-2022 for IM v7. @rem setlocal set I=%1 if "%I%"=="." set I= if "%I%"=="" ( set I=%IMG7% ) set OUTFILE=half.txt if not "%2"=="" if not "%2"=="." set OUTFILE=%2 set PREC=-precision 15 %I%magick -version>%OUTFILE% echo With Q16i and Q32f, these give #8000.>>%OUTFILE% %I%magick %PREC% xc:Black -evaluate Add 50%% txt:>>%OUTFILE% %I%magick %PREC% xc:Black -evaluate AddModulus 50%% txt:>>%OUTFILE% %I%magick %PREC% xc:Black -evaluate Sin 0 txt:>>%OUTFILE% %I%magick %PREC% xc:Black -evaluate Set 50%% txt:>>%OUTFILE% %I%magick %PREC% xc:White -evaluate Divide 2 txt:>>%OUTFILE% %I%magick %PREC% xc:White -evaluate Multiply 0.5 txt:>>%OUTFILE% %I%magick %PREC% xc:Black -function Polynomial 0.5 txt:>>%OUTFILE% %I%magick %PREC% xc:White -function Polynomial 0.5 txt:>>%OUTFILE% %I%magick %PREC% xc:White -function Polynomial 0.5,0 txt:>>%OUTFILE% %I%magick %PREC% xc:Black -function Sinusoid 1 txt:>>%OUTFILE% %I%magick %PREC% xc:Black xc:White -evaluate-sequence Mean txt:>>%OUTFILE% %I%magick %PREC% xc:Black xc:White -compose Mathematics -define compose:args=0,0.5,0.5,0 -composite txt:>>%OUTFILE% %I%magick %PREC% xc:Black xc:White -compose Mathematics -define compose:args=0,0,0,0.5 -composite txt:>>%OUTFILE% %I%magick %PREC% xc:Black xc:White +append -scale 1x1 txt:>>%OUTFILE% %I%magick %PREC% xc:Black xc:White -evaluate-sequence Mean txt:>>%OUTFILE% %I%magick %PREC% xc:Black -fx "0.5" txt:>>%OUTFILE% %I%magick %PREC% -size 100x1 gradient: -scale 1x1 txt:>>%OUTFILE% echo. >>%OUTFILE% echo With Q16i and Q32f, these give #7fff:>>%OUTFILE% %I%magick %PREC% xc:White -evaluate Subtract 50%% txt:>>%OUTFILE% %I%magick %PREC% xc:White -evaluate AddModulus 50%% txt:>>%OUTFILE% %I%magick %PREC% xc:gray(50%%) txt:>>%OUTFILE% echo. >>%OUTFILE% echo With Q16i, these give #7fff, but with Q32f they give #8000:>>%OUTFILE% %I%magick %PREC% xc:gray(50%%) txt:>>%OUTFILE% %I%magick %PREC% xc:srgb(50%%,50%%,50%%) txt:>>%OUTFILE% echo. >>%OUTFILE% echo These are arithmetically horrible in all Q:>>%OUTFILE% %I%magick %PREC% xc:gray50 txt:>>%OUTFILE% type %OUTFILE%
All images on this page were created by the commands shown, using:
%IMG7%magick -version
Version: ImageMagick 7.1.0-42 Q16-HDRI x64 396d87c:20220709 https://imagemagick.org Copyright: (C) 1999 ImageMagick Studio LLC License: https://imagemagick.org/script/license.php Features: Cipher DPC HDRI OpenCL Delegates (built-in): bzlib cairo freetype gslib heic jng jp2 jpeg jxl lcms lqr lzma openexr pangocairo png ps raqm raw rsvg tiff webp xml zip zlib Compiler: Visual Studio 2022 (193231332)
Source file for this web page is fiftypc.h1. To re-create this web page, run "procH1 fiftypc".
This page, including the images, is my copyright. Anyone is permitted to use or adapt any of the code, scripts or images for any purpose, including commercial use.
Anyone is permitted to re-publish this page, but only for non-commercial use.
Anyone is permitted to link to this page, including for commercial use.
Page version v1.0 15-March-2015.
Page created 27-Aug-2022 18:28:29.
Copyright © 2022 Alan Gibson.