Главная » 2025 » Ноябрь » 18 » UImage: графическая библиотека для Python
20:49
UImage: графическая библиотека для Python

UImage: open source библиотека для работы с изображениями в Python 3

Графическая open source библиотека UImage для Python 3.8+ является надстройкой над библиотеками Pillow (PIL) и ImageMagick. При этом она имеет свой собственный формат файла и дополнительные возможности. Если библиотека Pillow отсутствует, то выполняется попытка выполнить операцию с помощью библиотеки ImageMagick.

Библиотека, скорее всего, работает только в Windows x64. В других операционных системах работоспособность не проверялась и не гарантируется. Вполне возможно будет работать и в других операционных системах.

Библиотеки Python, Pillow, ImageMagick, NumPy и Matplotlib в комплект не входят.  Установка Python 3.8 под Windows подробно описана в документации (см. каталог docs\test_python\setup_python). Процесс установки Pillow, NumPy и Matplotlib предельно прост:

pip install Pillow
pip install numpy
pip install matplotlib

Версии этих библиотек, использованные при тестировании:

>>> import PIL
>>> PIL.__version__
'9.3.0'
>>> import numpy
>>> numpy.__version__
'1.23.4'
>>> import matplotlib
>>> matplotlib.__version__
'3.6.2'

Архив с библиотекой ImageMagick нужно  загрузить со страницы:

https://imagemagick.org/script/download.php

Для Windows x64 загрузить можно такой архив:

ImageMagick-7.1.2-8-portable-Q16-x64.7z

Версия библиотеки ImageMagick, используемая при тестировании:

C:\Users\Unicross>C:\ImageMagick\magick -version
Version: ImageMagick 7.0.11-13 Q16 x64 2021-05-17 https://imagemagick.org
Copyright: (C) 1999-2021 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Visual C++: 192829914
Features: Cipher DPC OpenCL
Delegates (built-in): bzlib cairo flif freetype gslib heic jng jp2 jpeg
 jxl lcms lqr lzma openexr pangocairo png ps raw rsvg tiff webp xml
 zip zlib

Поиск библиотеки ImageMagick выполняется в следующем порядке:

  • проверка наличия каталога ImageMagick на одном уровне с каталогом unicross_image библиотеки UImage. Внутри каталога ImageMagick должен быть файл magick.exe;
  • проверка наличия каталога ImageMagick в корне диска C:. Внутри каталога должен быть файл magick.exe;
  • проверка наличия каталога ImageMagick в корне диска D:. Внутри каталога должен быть файл magick.exe;
  • проверка наличия файла magick.exe в пути, прописанном в переменной окружения MAGICK_HOME.

Начиная с версии 1.2, можно указать путь к ImageMagick из программы:

from unicross_image.uhelper import usettings
usettings["magick_path"] = r"C:\ImageMagick\magick.exe";

from unicross_image.uimagegray import UImageGray
img = UImageGray(1, 1, create_arr=False)
print(img.get_image_magick_path()) # C:\ImageMagick\magick.exe

Следует учитывать, что доступ к файлу magick.exe из библиотеки ImageMagick выполняется напрямую, а не через Wand или биндинг. Это не очень эффективно с точки зрения производительности, но тем не менее работает, позволяя выполнить очень сложные операции на компилируемом языке. Простые операции удобно выполнять с помощью библиотеки UImage.

Проверим установку путем вывода версии библиотеки UImage:

import unicross_image

print(unicross_image.__version__) # 1.2.0
print(unicross_image.VERSION)     # ('1', '2', '0')

Обзор возможностей библиотеки

Библиотека UImage содержит следующие основные классы:

  • UImage — класс цветного изображения с 4-я каналами RGBA (int от 0 до 255);
  • UImageRGB — класс цветного изображения с 3-я каналами RGB (int от 0 до 255);
  • UImageGray — класс изображения в оттенках серого с одним каналом (int от 0 до 255);
  • UMask — класс, предназначенный для хранения маски или черно-белого изображения с одним каналом (тип bool);
  • UMat — описывает матрицу с произвольными значениями.

Для каждого класса изображения существует свой класс обработки (в конец названия класса изображения добавляется фрагмент Change) и свой класс рисования (в конец названия класса изображения добавляется фрагмент DrawPIL). Например, выполнить преобразование изображения класса UImageRGB можно с помощью методов из класса UImageRGBChange, а нарисовать что-либо можно с помощью методов класса  UImageRGBDrawPIL. Фрагмент PIL в конце названия класса рисования говорит о том, что рисование выполняется с помощью библиотеки Pillow.

Подключение библиотеки и импорт классов из модулей

Библиотека UImage поставляется в виде пакета unicross_image. Если программа расположена рядом с каталогом библиотеки, то подключение модуля из пакета и импорт класса выполняются примерно так:

from unicross_image.uimagergb import UImageRGB

Если программа расположена в другом месте, то предварительно нужно прописать путь к библиотеке в пути поиска модулей:

import sys
sys.path.append(r"D:\UImage")
from unicross_image.uimagergb import UImageRGB

Библиотека содержит 14 модулей. Импорт всех классов из этих модулей потребует довольно много инструкций import. С помощью этой инструкции (доступна с версии 1.2) можно импортировать сразу все основные классы:

from unicross_image import *

Пример использования:

from unicross_image import *

img = UImageRGB(300, 200, UColor("красный"))
print(img.get_num_channels())       # 3
# Преобразование в оттенки серого
img_gray = img.get_uimagegray()
print(img_gray.get_num_channels())  # 1
# Добавление альфа-канала
img_rgba = UImage.from_uimagergb(img, opacity=128)
print(img_rgba.get_num_channels())  # 4

Импортируются следующие классы:

__all__ = [
   'UPoint', 'USize', 'URect', 'UColor', 'UImage', 'UImageChange',
   'UMat', 'UImageRGB', 'UImageRGBChange',
   'UImageGray', 'UMask', 'UImageGrayChange', 
   'UFont', 'UImageDrawPIL', 'UImageRGBDrawPIL', 'UImageGrayDrawPIL']

Примеры использования библиотеки

Пример загрузки изображения из файла, выполнения поворота изображения на 90 градусов и сохранения изображения в файл:

from unicross_image.uimagergb import UImageRGB
from unicross_image.uimagergbchange import UImageRGBChange

img = UImageRGB.load("foto.jpg")
if img:
    img = UImageRGBChange.rotate_90(img)
    if img:
        if img.save("foto2.jpg"):
            print("Изображение успешно сохранено")
        else:
            print("Не удалось сохранить изображение")
    else:
        print("Не удалось повернуть изображение")
else:
    print("Не удалось загрузить изображение")

Пример создания нового изображения красного цвета с размерами 300x200px и сохранения его в файл в формате PNG:

from unicross_image.ucolor import UColor
from unicross_image.uimagergb import UImageRGB

img = UImageRGB(300, 200, UColor("красный"))
print(img.get_width())         # 300
print(img.get_height())        # 200
print(img.get_num_channels())  # 3
print(img.get_arr_len())       # 180000
img.save("foto2.png")

Характерной особенностью библиотеки является хранение значений матрицы в одномерном списке и возможность непосредственного доступа к этому списку:

from unicross_image.ucolor import UColor
from unicross_image.uimagergb import UImageRGB

img = UImageRGB(3, 2, UColor("красный"))
print(img.arr)
# [255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0,
# 255, 0, 0]
# Проверка валидности
if img.is_valid():
    # Перебор
    for item in img.arr:
        print(item)
    
    # Изменение
    r, g, b = 0, 128, 255
    for i in range(0, img.get_arr_len(), img.get_num_channels()):
        img.arr[i] = r
        img.arr[i + 1] = g
        img.arr[i + 2] = b

print(img.arr)
# [0, 128, 255, 0, 128, 255, 0, 128, 255, 0, 128, 255, 0, 128, 255,
#  0, 128, 255]

Можно использовать уже существующий список для создания объекта:

from unicross_image.uimagergb import UImageRGB

arr = [255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0,
       255, 0, 0]
img = UImageRGB(3, 2, create_arr=False)
img.arr = arr
print(img.is_valid()) # False
img.update_arr_len()  # Обновление данных
print(img.is_valid()) # True
print(img.arr)
# [255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0,
# 255, 0, 0]

В любой момент времени можно преобразовать объект одного класса в объект другого класса:

from unicross_image.ucolor import UColor
from unicross_image.uimage import UImage
from unicross_image.uimagergb import UImageRGB

img = UImageRGB(300, 200, UColor("красный"))
print(img.get_num_channels())       # 3
# Преобразование в оттенки серого
img_gray = img.get_uimagegray()
print(img_gray.get_num_channels())  # 1
# Добавление альфа-канала
img_rgba = UImage.from_uimagergb(img, opacity=128)
print(img_rgba.get_num_channels())  # 4

Стандартные классы позволяют работать только с целочисленными значениями. Для значений другого типа предназначен класс UMat. Например, можно преобразовать объект изображения в матрицу с вещественными значениями, выполнить какие-либо операции, а затем обратно преобразовать матрицу в объект изображения:

from unicross_image.ucolor import UColor
from unicross_image.uimagergb import UImageRGB

img = UImageRGB(2, 2, UColor(255, 0, 0))
print(img.arr)
# [255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0]
m = img.get_umat_64f()
print(m.arr)
# [1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
img = UImageRGB.from_umat_64f(m)
print(img.arr)
# [255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0]

Использование Pillow в программе на Python

Графическая библиотека UImage тесно связана с библиотекой Pillow. Загрузка изображений из файлов стандартных форматов, сохранение в файл, а также выполнение различных преобразований в основном выполняется средствами библиотеки Pillow. Эти операции можно выполнить и с помощью библиотеки ImageMagick, но вот рисование и вывод текста возможны только при условии доступности библиотеки Pillow. В любой момент времени имеется возможность преобразования объектов из разных библиотек:

from PIL import Image
from unicross_image.uimagergb import UImageRGB

img = Image.open("foto.jpg")
print(img.size)        # (500, 333)
img2 = UImageRGB.from_pil_image(img)
print(img2.get_size()) # USize(width=500, height=333)
img3 = img2.get_pil_image()
print(img3.size)       # (500, 333)

Использование ImageMagick в программе на Python

Если библиотека Pillow недоступна, то автоматически вызывается метод, выполняющий аналогичную операцию с помощью библиотеки ImageMagick. Если библиотека ImageMagick также недоступна, то метод вернет значение None. Можно сразу вызвать метод, выполняющий операцию с помощью библиотеки ImageMagick. В названиях таких методов последним будет фрагмент "_im". Выполним все операции только с помощью библиотеки ImageMagick:

from unicross_image.uimagergb import UImageRGB
from unicross_image.uimagergbchange import UImageRGBChange

img = UImageRGB.load_im("foto.jpg")
if img:
    img = UImageRGBChange.rotate_90_im(img)
    if img:
        if img.save_im("foto2.jpg"):
            print("Изображение успешно сохранено")
        else:
            print("Не удалось сохранить изображение")
    else:
        print("Не удалось повернуть изображение")
else:
    print("Не удалось загрузить изображение")

Форматы файлов UImage и PPM

На самом деле стандартные классы библиотеки UImage могут работать и без библиотек Pillow и ImageMagick. Просто станет нельзя загрузить изображение из стандартных графических форматов и сохранить изображение в этих форматах. Но остается возможность использовать форматы без сжатия, например, формат PPM, а также собственный формат библиотеки .uimage:

from unicross_image.uimagergb import UImageRGB

# Загрузка PPM
img = UImageRGB.load_ppm_p6("foto.ppm")
if img:
    print(img.get_size()) # USize(width=500, height=333)
    # Сохранение PPM
    img.save_ppm_p6("foto2.ppm")
    # Сохранение .uimage
    img.save_uimage_rgb("foto.uimage")
else:
    print("Не удалось загрузить изображение")

# Загрузка .uimage
img = UImageRGB.load_uimage("foto.uimage")
if img:
    print(img.get_size()) # USize(width=500, height=333)
else:
    print("Не удалось загрузить изображение")

Формат файла определяется по расширению файла, поэтому можно просто использовать методы load() и save() без явного указания типа файла:

from unicross_image.uimagergb import UImageRGB

# Загрузка PPM
img = UImageRGB.load("foto.ppm")
if img:
    print(img.get_size()) # USize(width=500, height=333)
    # Сохранение PPM
    img.save("foto2.ppm")
    # Сохранение .uimage
    img.save("foto.uimage")
else:
    print("Не удалось загрузить изображение")

# Загрузка .uimage
img = UImageRGB.load("foto.uimage")
if img:
    print(img.get_size()) # USize(width=500, height=333)
else:
    print("Не удалось загрузить изображение")

Взаимодействие с Tkinter и объектом PhotoImage

Графическая библиотека UImage тесно связана также с библиотекой Tkinter. Для этого предназначен класс UHelperTk. Отобразим изображение в компоненте Canvas:

from unicross_image.uimagergb import UImageRGB
from unicross_image.uhelper_tk import UHelperTk
from tkinter import *
 
root = Tk()
root.title("Взаимодействие с Tkinter и объектом PhotoImage")
root.geometry("700x450")

canvas = Canvas(bg="white", width=600, height=400)
canvas.pack(anchor=CENTER, expand=1)

img = UImageRGB.load("foto.jpg")
# Преобразование в PhotoImage
img2 = UHelperTk.uimage_to_photoimage(img)

canvas.create_image(10, 10, anchor=NW, image=img2)
root.mainloop()

Кстати, если библиотеки Pillow и ImageMagick недоступны, то можно загрузить изображение из стандартных графических форматов с помощью объекта PhotoImage из библиотеки Tkinter. В классе UHelperTk для этой цели предусмотрены специальные методы.

Взаимодействие с библиотекой NumPy

С помощью класса UHelperNP можно преобразовать объект изображения в массив NumPy, а также выполнить обратное преобразование:

from unicross_image.ucolor import UColor
from unicross_image.uimagergb import UImageRGB
from unicross_image.uhelper_np import UHelperNP

img = UImageRGB(3, 2, UColor(255, 0, 0))

# Преобразование UImageRGB в массив NumPy
arr = UHelperNP.uimage_to_ndimage(img)
print(arr.shape)  # (2, 3, 3)
print(arr.dtype)  # uint8
print(arr)
# [[[255   0   0]
#  [255   0   0]
#  [255   0   0]]
#
# [[255   0   0]
#  [255   0   0]
#  [255   0   0]]]

# Преобразование массива NumPy в UImageRGB
img2 = UHelperNP.ndimage_to_uimage(arr)
print(img2) # UImageRGB(width=3, height=2)

Класс UHelperNP содержит также методы для выполнения различных преобразований для изображений в оттенках серого, например, можно повернуть изображение на угол кратный 90 градусам, зеркально отразить по горизонтали или вертикали, обрезать, вставить одно изображение в другое, добавить рамку или паддинг и др.

Взаимодействие с библиотекой Matplotlib

Класс UHelperPlt позволяет отображать изображения и гистограммы с помощью библиотеки Matplotlib. Отобразим изображение в диалоговом окне:

from unicross_image.uhelper_plt import UHelperPlt, UImageRGB

img = UImageRGB.load("foto.jpg")
UHelperPlt.imshow(img)

Вычислим гистограммы и отобразим графики сразу для всех каналов:

from unicross_image.uhelper_plt import UHelperPlt, UImageRGB

img = UImageRGB.load("foto.jpg")
UHelperPlt.uimagergb_show_hist(img)

Настройка пути к каталогу для временных файлов

По умолчанию библиотека UImage должна быть расположена в каталоге, запись в который не требует прав администратора и путь к которому не содержит запрещенных символов (например, русских букв). Иначе работа с библиотекой ImageMagick станет невозможной, т. к. взаимодействие выполняется через файловую систему и командную строку. Рекомендуемые пути:

C:\UImage\unicross_image
D:\UImage\unicross_image
C:\ImageMagick\magick.exe
D:\ImageMagick\magick.exe

Начиная с версии 1.2 имеется возможность обойти это ограничение и указать местоположение каталога для временных файлов автоматически или вручную:

  • если путь к каталогу с библиотекой соответствует регулярному выражению:
r"^[a-zA-Z0-9/\\:\._\- ]+$"

то проверяется возможность записи в каталог unicross_image\tmp. Если каталог доступен для записи, то он будет использоваться для сохранения временных файлов;

  • если каталог unicross_image\tmp не доступен для записи, то выполняется поиск системного каталога для временных файлов. Если этот каталог существует и в пути к нему нет запрещенных символов, то внутри этого каталога создается каталог _uimagetmp и производится попытка записи файла в него. Если каталог доступен для записи, то он будет использоваться для сохранения временных файлов;
  • если системный каталог не соответствует требованиям, то выполняется тестирование текущего рабочего каталога. Если в пути к нему нет запрещенных символов, то внутри этого каталога создается каталог _uimagetmp и производится попытка записи файла в него. Если каталог доступен для записи, то он будет использоваться для сохранения временных файлов;
  • если текущий рабочий каталог также не соответствует требованиям, то любая попытка создать экземпляр класса изображения приведет к генерации исключения. Обойти это исключение можно с помощью словаря usettings.

Если путь не найден, то usettings["tmp_path"] будет содержать значение None, которое можно обработать из программы:

from unicross_image.uhelper import usettings
if usettings["tmp_path"] is None:
    usettings["tmp_path"] = my_tmp_path;

Изменение значения usettings["tmp_path"] изменяет путь для всех экземпляров:

from unicross_image.uhelper import usettings
from unicross_image import *

print(usettings["tmp_path"])
# D:\UImage\unicross_image\tmp

usettings["tmp_path"] = r"D:\UImage";

img = UImage(1, 1, create_arr=False)
print(img.get_tmp_path()) # D:\UImage
img2 = UImageRGB(1, 1, create_arr=False)
print(img2.get_tmp_path()) # D:\UImage
img3 = UImageGray(1, 1, create_arr=False)
print(img3.get_tmp_path()) # D:\UImage

Модули библиотеки UImage

Внутри пакета  unicross_image расположены следующие модули:

  • ucolor.py — вспомогательный модуль для работы с цветом. Содержит следующие идентификаторы:
  • класс UColor для хранения цвета RGBA (значения от 0 до 255);
  • объекты URGBA и URGB;
  • словарь COLOR_NAMES со списком всех поддерживаемых названий цветов;
  • uhelper.py — вспомогательный модуль, содержащий следующие идентификаторы:
  • класс UPoint описывает координаты точки (тип int) в двумерном пространстве;
  • класс UPointF описывает координаты точки (тип float) в двумерном пространстве;
  • класс USize описывает размеры прямоугольной области (тип int);
  • класс USizeF описывает размеры прямоугольной области (тип float);
  • класс URect описывает координаты и размеры (тип int) прямоугольной области;
  • uhelper_pil.py — содержит класс UHelperPIL, предназначенный для выполнения загрузки и сохранения файла .uimage для библиотеки Pillow;
  • uhelper_tk.py — содержит класс UHelperTk, предназначенный для выполнения преобразований между UImage и Tk PhotoImage;
  • uhelper_np.py — содержит класс UHelperNP, предназначенный для выполнения преобразований с помощью библиотеки NumPy;
  • uhelper_plt.py — содержит класс UHelperPlt, предназначенный для отображения изображений и гистограмм с помощью библиотеки Matplotlib;
  • uimage.py — содержит класс UImage, предназначенный для хранения цветного изображения с 4-я каналами RGBA (int от 0 до 255);
  • uimagechange.py — содержит класс UImageChange, предназначенный для выполнения преобразований UImage (средствами Pillow или ImageMagick и без). Почти все методы принимают объект UImage и возвращают копию преобразованного объекта UImage или None;
  • uimagergb.py — содержит класс UImageRGB, предназначенный для хранения цветного изображения с 3-я каналами RGB (int от 0 до 255);
  • uimagergbchange.py — содержит класс UImageRGBChange, предназначенный для выполнения преобразований UImageRGB (средствами Pillow или ImageMagick и без). Почти все методы принимают объект UImageRGB и возвращают копию преобразованного объекта UImageRGB или None;
  • uimagegray.py — содержит следующие идентификаторы:
  • класс UImageGray, предназначенный для хранения изображения в оттенках серого с одним каналом (int от 0 до 255);
  • класс UMask, предназначенный для хранения маски или черно-белого изображения с одним каналом (тип bool);
  • uimagegraychange.py — содержит класс UImageGrayChange, предназначенный для выполнения преобразований UImageGray (средствами Pillow или ImageMagick и без). Почти все методы принимают объект UImageGray и возвращают копию преобразованного объекта UImageGray или None;
  • uimagedraw.py — модуль для рисования. Содержит следующие идентификаторы:
  • класс UFont, описывающий характеристики шрифта;
  • класс UImageDrawPIL, предназначенный для рисования на UImage средствами Pillow;
  • класс UImageRGBDrawPIL, предназначенный для рисования на UImageRGB средствами Pillow;
  • класс UImageGrayDrawPIL, предназначенный  для рисования на UImageGray средствами Pillow;
  • umat.py — содержит класс двумерной матрицы UMat.
Название архива: UImage_1_2_0.zip
md5: 048da9ea93d3067d2f2df0330389a086
sha256: 1c6e34f1245878ff488504eeb9151742e539a7ef294af081fe563b52d32aeb36
ImageMagick License (https://imagemagick.org/script/license.php)

Download UImage version 1.2.0Donate

Категория: UImage | Просмотров: 41 | Добавил: unicross | Теги: графическая библиотека, Python, PIL, UImage, ImageMagick, Tkinter | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Категории раздела
Списки слов [10]
Списки слов и словари
OCR [4]
Оптическое распознавание символов
UImage [80]
Графическая библиотека для Python
UImage C [7]
Графическая библиотека для Python
Программы [4]
Полезные программы
Прочее [3]
Другие темы
Календарь
«  Ноябрь 2025  »
Пн Вт Ср Чт Пт Сб Вс
     12
3456789
10111213141516
17181920212223
24252627282930