Сохранение QPixmap в формате JPEG приводит к вертикальным линиям - PullRequest
1 голос
/ 22 августа 2011

Пользователь установил наше приложение на серверный ПК, поделился установочной директорией как сетевой диск Z: и теперь открывает приложение с разных клиентских ПК по всему своему магазину. Все работает нормально, за исключением одной ошибки на одном из ПК:

На проблемном ПК приложение может загружать .jpg файлы для предметов инвентаря просто отлично и отображать соответствующую QPixmap в QLabel. Если у предмета инвентаря, который он просматривает в данный момент, еще не назначено изображение, он может открыть диалоговое окно файла, выбрать изображение и правильно его отобразить. Однако сохранение (нового / измененного) QPixmap в виде .jpg сохраняет его на диске в виде серии цветных вертикальных линий на черном фоне:

(this should actually be some jewellery)

Сохранение выполняется с помощью QPixmap::save( const QString & fileName, ...) с программным именем файла, установленным на "<some_id>.jpg" для обозначения желаемого формата файла. Возвращает true, но полученный файл выглядит как современное искусство.

Однако сохранение изображений отлично работает на сервере и других клиентах.

Сервер и проблемный ПК работают под управлением Windows XP с одинаковым уровнем исправлений.

Process Explorer показывает идентичные библиотеки DLL для процесса приложения на сервере и проблемном ПК, за исключением проблемного ПК, использующего dnsapi.dll, а сервер этого не делает.

Process Explorer также показывает, что как на сервере, так и на клиенте библиотека Qt, используемая для работы с JPEG, имеет вид \Device\LanmanRedirector\<server>\<app>\plugins\imageformats\qjpeg4.dll, и поиск по всему диску на проблемном ПК для qjpeg*.dll оказался пустым, поэтому приложение должно использовать одинаковый код обработки JPEG на обоих компьютерах.

Есть предложения?

(РЕДАКТИРОВАТЬ: добавлены ОС и состояние исправления в описании проблемы.)

РЕДАКТИРОВАТЬ: Решение: на проблемной машине у нас была глубина цвета 16 бит на дюйм. Установка этого значения в 32 bpp решила нашу проблему мгновенно. Я также заменил
_pm.save( sDestFileName )
с
_pm.toImage().convertToFormat( QImage::Format_RGB32 ).save( sDestFileName )
чтобы мы не сталкивались с этим на каждом старом клиентском компьютере, работающем со скоростью менее 32 бит / с.

1 Ответ

2 голосов
/ 22 августа 2011

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

  • Скопируйте qjpeg4.dll в рабочий каталог клиента
  • Повреждено ли изображение при сохранении в формате PNG или GIF?
  • Преобразование ваших данных в QImage и работа с ним.
  • Рассмотрим формат байтов (я обычно использую ARGB32, потому что он выровнен по int)
  • Чтобы проверить, где проблемапроисходит, вы можете попробовать преобразовать изображение в формат JPG, а затем просмотреть его в окне отладки.

Функция, приведенная ниже, взята из программы OSS , которую я написал.Вы можете попробовать использовать его, а затем отобразить содержимое QImage, указанного во втором параметре:

//! Saves image with JPEG compression in given quality (0 - 100, Qt's scale)
//! @param[in] in The lossless input image
//! @param[out] out The image to save to using JPEG compression
//! @param quality The quality level (0 - 100, 0 the most compressed)
//! @return The size of the saved image
quint32 Window::imageSaveLossy(QImage &in, QImage &out, quint8 quality)
{
        quint32 retval;
        QByteArray ba;
        QBuffer buffer(&ba);
        buffer.open(QIODevice::WriteOnly);

        QImage temp(in.size(), QImage::Format_ARGB32);
        temp.fill(QColor(Qt::white).rgb());
        QPainter painter(&temp);
        painter.drawImage(0, 0, in);

        temp.save(&buffer, "JPG", quality);
        out.loadFromData(ba, "JPG");
        retval = (quint32)ba.size();
        buffer.close();
        return retval;
}
...