Package: image-intensities
image_intensitiesPython implementation of the greatderpibooru/image_intensities.The algorithmic overview is to convert the image into the yuv colorspace, drop the u and v components,
and then average the y component over 4 evenly-spaced rectangles on the image dimensions.Usagefromimage_intensitiesimportpng_intensities,jpg_intensities,image_intensities,Intensities# Let's calculate some valuesluma_a=png_intensities('/absolute/path/to/954482.png')# image can ge found in the tests folder.luma_b=jpg_intensities('/absolute/path/to/2544057.jpg')# image can ge found in the tests folder.# if you don't know the file type, you can have it picked up with the `mimetype` module:luma_b=image_intensities('/absolute/path/to/2544057.jpg')# image can ge found in the tests folder.# returns something likeluma_a=Intensities(nw=35.832628091300684,ne=10.513891063388744,sw=20.76546499989676,se=20.831389937866714)luma_b=Intensities(nw=8.284639125603292,ne=8.466390155604937,sw=22.851929679674072,se=23.26008498727572)# You can compare them, exact match (which is probably not what you want, see .compare(…) below)luma_a==luma_b# -> False# or a distance comparisonluma_a.compare(luma_b,distance=0.25)# -> False  # those two images are very different, after allA good distance is usually between0.2and0.5, the default is0.25.Pure PythonThere's also a pure python version, which thanks to PIL/Pillow supports about every image type:⚠️ Note: You need to installPillow(pip install Pillow) for this to work, seeDependenciesbelow.⚠️ Note: For animated image types it will probably use the first frame.fromimage_intensities.pure_pythonimportpng_intensities,jpg_intensities,image_intensities,Intensitiesluma=image_intensities('/path/to/image.gif')# returns something likeluma==Intensities(nw=0.42,ne=0.44,sw=0.58,se=0.69)DocumentationIf not mentioned otherwise, those are available for both the speed up native c and the pure python variant.classIntensities🔝This is the class returned by the calculations, containing the 4 quadrant sums.FieldTypeDescriptionnwfloatthe first (top left) quadrantnefloatthe second (top right) quadrantswfloatthe third (bottom left) quadrantsefloatthe last (bottom right) quadrantdefpng_intensities(…)🔝This function calculates the sums over a given PNG file.ParameterTypeRequiredDescriptionfilenamestrYesThe absolute path to the PNG file to run the sums over.defjpg_intensities(…)🔝This function calculates the sums over a given JPG file.ParameterTypeRequiredDescriptionfilenamestrYesThe absolute path to the JPG file to run the sums over.defimage_intensities(…)🔝This function calculates the sums over a given file, with unknown file type.Note: if you're using the cffi bindings, only PNG and JPEG are available natively. It will try to use Pillow/PIL if installed to read other formats.Note: if you're using the pure python version, Pillow/PIL needs to be installed.ParameterTypeRequiredDescriptionfilenamestrYesThe absolute path to the JPG file to run the sums over.defpixel_array_intensities(…)🔝This function calculates the sums over the given image pixel data.Note, the given list ofpixelshas to have a length ofwidth x heightfor the tuple form, orwidth x height x 3for the continuous integer stream.ParameterTypeRequiredDescriptionpixelsList[int] or List[Tuple[int, int, int]]YesList of pixel values, either a tuple of(R, G, B)integers (0-255) or a continuous list ofR,GandBvalues of pixels.widthintYesWidth of the image, needed to figure out the quadrant a pixel is in.heightintYesHeight of the image, needed to figure out the quadrant a pixel is in.defpixel_bytes_intensities(…)🔝This function calculates the sums over the given image pixel data.Note, the given list ofpixelshas to have a length ofwidth x height.ParameterTypeRequiredDescriptionpixelsbytesYesA binary stream ofR,GandBvalues, repeated for every pixel. (For example it could look likeb'\0x255\0x0\0x44\0x58\0x0\0x69...').widthintYesWidth of the image, needed to figure out the quadrant a pixel is in.heightintYesHeight of the image, needed to figure out the quadrant a pixel is in.DependenciesC-ExtensionMacOSbrewinstalllibpng(tested to work with 1.6.37)Ubuntu(There's also a version forDockerfilesavailable)sudoapt-getupdate
sudoapt-getinstalllibpng-devDockerfile (Ubuntu based)apt-getupdate-y&&apt-getinstall-ylibpng-dev&&apt-getclean&&rm-rfv/var/lib/apt/lists/*⚠️ Make sure you pull a recent release of the python docker image (even if it's an older python version!).
Especially if you're getting errors complaining about apng_set_longjmp_fnfunction when you try to use it.
As time of writing the 2-month old version did not work, but the newest releases (python:3.6:6ac87e65b6d0,pythong:3.9:1b33974176a3) ones have that fixed.Pure python algorithm(optional)This one is usually not needed, unless you wanna benefit from pillow's ability to read the strangest image formats.
But probably it's faster to write it to disk as either.jpgor.pngand use the native C versions as above.pipinstallPillowInstallationSee dependencies above, and make sure those are installed as needed.Install via pippipinstallimage_intensitiesMac OS:CPPFLAGS='-I/usr/local/include/'LDFLAGS='-L/usr/local/lib/'pipinstallimage_intensitiesFrom sourceE.g. you checked out this repository:pythonsetup.pyinstallMac OS:CPPFLAGS='-I/usr/local/include/'LDFLAGS='-L/usr/local/lib/'pythonsetup.pyinstallMinimal installation exampleUsing docker as it already has a workinglibpng-dev:dockerpullpython:3.9
dockerrun-it--rmpython:3.9bash
pipinstallimage_intensities# test importpython-c"import image_intensities as it; print(it._intensities.ffi)"# test with a pngwgethttps://derpicdn.net/img/download/2015/8/9/954482.png-O/tmp/954482.png
python-c"from image_intensities import png_intensities; print(png_intensities('/tmp/954482.png'))"# test with a jpgwgethttps://derpicdn.net/img/download/2021/2/4/2544057.jpg-O/tmp/2544057.jpg# we need to use an absolute path!python-c"from image_intensities import jpg_intensities; print(jpg_intensities('/tmp/2544057.jpg'))"