Найти - Пользователи
Полная версия: Сжатие изображения при создании pdf-файла.
Начало » GUI » Сжатие изображения при создании pdf-файла.
1 2
Pluto
Используются PyQt4 и twain
 pixmap = QtGui.QPixmap()
source.request_acquire(0, 0)
result = sf.source.XferImageNatively()
rawData = twain.DIBToBMFile(result[0])
pixmap.loadFromData(QtCore.QByteArray(rawData)) # картинка получается из данных со сканера. Используется модуль pytwain-master
# теперь картинку загоняем в pdf посредством QPrinter
printer = QtGui.QPrinter()
printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
printer.setOutputFileName("pdf.pdf")
printer.setPageMargins(0, 0, 0, 0, QtGui.QPrinter.Millimeter)
printer.setResolution(dpi)
painter = QtGui.QPainter()
painter.begin(printer)
painter.drawImage(0, 0, pixmap) # Как этот pixmap ужать???????
painter.end()

Как можно уменьшить размер получаемого pdf-файла? Точнее картинки в него помещаемой?
Если картинку, которую я сканирую, отсканировать стандартными средствами винды, то можно получить jpg-картинку размером в примерно 200 кб. Мой же pdf-файл с картинкой получается более 600 кб. И я даже не понимаю в каком вообще формате эта картинка в pdf попадает-то.

P.S. Естественно, при сканировании средствами винды и при сканировании посредством модуля twain я использую одинаковые параметры цветности и dpi.
PEHDOM
Pluto
# Как этот pixmap ужать???????
Имхо вы неправильно подходите,вам не нужно ничего делать с пиксмапом, вам нужно настаивать принтер. Смотрите сколько всего у КуПринтера есть: http://www.doc.crossplatform.ru/qt/4.7.x/qprinter-members.html
Там и дипиай, и глубина, и разрешение… сравните с каими параметрами оно создаеться и параметры вашего ПДФ-а который вы получаете при сканировании штатной тулзой в венде.
Или, если не выйдет, смотрите в сторону других утилит типа fpdf или PIL там возможно указать качетво, оптимизацию, DPI и тд.. выходного файла.
Pluto
Дык, как раз таки дипиай, глубину и разрешение мне трогать и не надо. Они должны оставаться такими с какими было отсканировано изображение. А вот само итоговое изображение можно было бы и поджать (jpg). Т.е. нужна настройка сжатия изображения или jpg-качества (сильнее-слабее).
Pluto
Решение!
Как говорится, хочешь узнать как сделать невозможную вещь? - Загляни в родную документацию!

 tmp_bytes = QtCore.QByteArray() # Массив байтов
tmp_buffer = QtCore.QBuffer(tmp_bytes) # Буфер. В качестве параметра массив байтов. 
tmp_buffer.open(QtCore.QIODevice.WriteOnly) # Открываем буфер на запись
pixmap.save(tmp_buffer, "jpg", 5) # Записываем в буфер нашу jpg-картинку с нужным сжатием. 5 тут только для примера, это очень сильное сжатие.
                                
jpg_pixmap = QtGui.QPixmap() # создаём новый pixmap
jpg_pixmap.loadFromData(tmp_bytes) # запихиваем в него содержимое нашего Массива байтов
tmp_buffer.close() # буфер закрыли.
                
painter.drawPixmap(0, 0, jpg_pixmap) # вуаля, в моём pdf-файле появилась сжатая-пержатая картинка в формате jpg!

Возможно это какой-нибудь неоптимальный вариант. Но, главное, работает.
Pluto


 from PyQt4 import QtGui
from PIL import ImageEnhance
from PIL import Image as PILImage
pil_image_bmp = PILImage.open(io.BytesIO(scanned_rawdata)) # получаем картинку в формате bmp из отсканированных данных
modified_pil_image_bmp = sf.bright_contrast(pil_image_bmp) # изменяем яркость и контраст
# Переводим в jpeg совместными средствами PyQt и PIL
tmp_bytes = QtCore.QByteArray()
tmp_buffer = QtCore.QBuffer(tmp_bytes)
tmp_buffer.open(QtCore.QIODevice.WriteOnly)
modified_pil_image_bmp.save(tmp_buffer, "JPEG", quality = 50))
qt_jpg_pixmap = QtGui.QPixmap()
qt_jpg_pixmap.loadFromData(tmp_bytes)
tmp_buffer.close()
def bright_contrast(sf, pil_image):
        bright = ImageEnhance.Brightness(pil_image)
        pil_image_bright = bright.enhance(1.1) # яркость
        contrast = ImageEnhance.Contrast(pil_image_bright)
        pil_image_bright_and_contrast = contrast.enhance(2) # контраст
        return pil_image_bright_and_contrast

Всё равно jpeg-файл, получаемый в qt_jpg_pixmap, выходит большим!
Как ещё можно его ужать? Вот это вот quality = 50 влияет на размер картинки (в килобайтах) как-то слабовато. Хотя картинку исправно портит сжатием, при малых значениях.

Как-то ж умудряется Хьюлетт-паккардовская программка, идущая в комплекте со сканером, выдавать хорошую картинку изображения килобайт в двести, а моя программа эту же картинку меньше 500 килобайт делать не хочет.
PEHDOM
Pluto
Как-то ж умудряется Хьюлетт-паккардовская программка, идущая в комплекте со сканером, выдавать хорошую картинку изображения килобайт в двести, а моя программа эту же картинку меньше 500 килобайт делать не хочет.
Отканил у себя кенонвской тулзой, загнал в ПДФ-ку, потом открыл ПДФ-ку в фотошпе, благо он это умеет, почемуто размер картинки в пикселах раза в два меньше чем получается пиксмап на выходе при том же dpi, может поэтому и размер меньше?
Pluto
Эх ты ж! Действительно!
В хьюлет-паккардовской программке pdf-ка (точнее, картинка в pdf-ке) тоже уменьшается в размерах. Вот ведь редиска-то! А я уже всю голову сломал.

Там ещё в настройках можно выбрать: “Документ” (который я и выбирал) или “Изображение”. В первом случае изображение будет уменьшено в пикселах; а во втором случае варианта с PDF вообще нет, и картинка получится по весу такая же большая как и в моей программе (даже больше).
Pluto
Нет! Ничего не действительно.
Я открывал pdf-ку Gimp'ом. В нём по-умолчанию стояло 100ppi для импорта. И импортируемая картинка оказывалась меньше в пикселах.
Если выставить 200ppi, то импортируемая картинка получится больше в пикселах.
Если её сохранить в jpg, она опять займёт свои 400-500 Кб.

Так что ни черта по-прежнему не понятно, как хьюлетовская и кеноновская прога создают pdf-ку на 200 кб.
Я попытался сделать resize для PIL Image - только резко ухудшил детализацию.
Причём моя картинка с изменённым размером становится плохо читаемой (текст на картинке),
а картинка с тем же пиксельным размером (после импорта в Gimp) у хью с кеноном получается намного детальнее.

Мыстика…
Pluto
Хм. Сделал сохранению напрямую jpg-картинки из объекта PIL.Image на диск - параметр качества jpg заметно влияет на килобайтовый вес изображения. При этом не сильно портя картинку.
Но в pdf-то я её загоняю посредством QPrinter. Чёрт его знает в каком виде он картинку в pdf запихивает. В итоге pdf-ка практически не уменьшается в размерах, какие бы я параметры для jpg не задавал.
Либо нужно тщательнее изучить QPrinter, либо вообще воспользоваться сторонним модулем для создания pdf.
Pluto
Решил использовать для pdf модуль fpdf2, а эта редиска в качестве параметра для вставки картинки принимает только путь к файлу на диске, либо url.

….
Ну да ладно. Буду пихать временные jpg во временную папку, а потом чистить её, по выходу из программы.
За то у меня НАКОНЕЦ-ТО получился pdf нужного “веса” и качества. И функция PIL.Image.resize() пригодилась.

Теперь осталось только красивостей в интерфейс моей программы добавить и можно пользоваться.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB