I use the following code to convert Magick::Image
to QImage
:
QImage
convert( const Magick::Image & img )
{
QImage qimg( static_cast< int > ( img.columns() ),
static_cast< int > ( img.rows() ), QImage::Format_RGB888 );
const Magick::PixelPacket * pixels;
Magick::ColorRGB rgb;
for( int y = 0; y < qimg.height(); ++y)
{
pixels = img.getConstPixels( 0, y, static_cast< std::size_t > ( qimg.width() ), 1 );
for( int x = 0; x < qimg.width(); ++x )
{
rgb = ( *( pixels + x ) );
qimg.setPixel( x, y, QColor( static_cast< int> ( 255 * rgb.red() ),
static_cast< int > ( 255 * rgb.green() ),
static_cast< int > ( 255 * rgb.blue() ) ).rgb());
}
}
return qimg;
}
This code works, but with one test image with 8000x6000
resolution I've got nullptr at the first line of Magick::Image
. img.getConstPixels( 0, 0, 8000, 1 )
just returns nullptr
. How can it be possible? Maybe do I do something wrong here? Thanks.
ImageMagick
version is 6.9.11.60
on Kubuntu 22.04
.
I actually open GIF with Magick::readImages( ... )
, then Magick::coalesceImages()
, and then convert each frame of the GIF into QImage
. I downloaded test GIF, that brokes ImageMagick
, and this GIF is here.
Reproducible example:
#include <Magick++.h>
#include <QImage>
#include <QDebug>
int main()
{
Magick::InitializeMagick( nullptr );
std::vector< Magick::Image > imgs;
Magick::readImages( &imgs, "sample-gif-file-for-Testing.gif" );
std::vector< Magick::Image > cimgs;
Magick::coalesceImages( &cimgs, imgs.begin(), imgs.end() );
int i = 0;
for( auto it = cimgs.cbegin(), last = cimgs.cend(); it != last; ++it )
{
qDebug() << QString( "frame #%1" ).arg( i );
QImage qimg( static_cast< int > ( it->columns() ),
static_cast< int > ( it->rows() ), QImage::Format_RGB888 );
const Magick::PixelPacket * pixels;
Magick::ColorRGB rgb;
for( int y = 0; y < qimg.height(); ++y)
{
pixels = it->getConstPixels( 0, y, static_cast< std::size_t > ( qimg.width() ), 1 );
qDebug() << QString( "pixels from line %1" ).arg( y ) << pixels;
for( int x = 0; x < qimg.width(); ++x )
{
rgb = ( *( pixels + x ) );
qimg.setPixel( x, y, QColor( static_cast< int> ( 255 * rgb.red() ),
static_cast< int > ( 255 * rgb.green() ),
static_cast< int > ( 255 * rgb.blue() ) ).rgb());
}
}
++i;
}
return 0;
}
The problem is that if GIF image has one frame, then
Magick::coalesceImages( &cimgs, imgs.begin(), imgs.end() );
can break that frame, so do coalesceImages()
only if imgs.size() > 1
.