Page 1 of 1

Writepixels() gives me BGR upside-down image

Posted: 2009-01-23T06:44:33-07:00
by jpuskas
I'm writing a Directshow source filter in VC++. It collects bmp files from a directory and saves an AVI from them. I've selected ImageMagick to crop and unsharp the images a bit.
The DS filter needs a BYTE buffer with pixel data to save a frame, so I tried to fill it with writepixels(). When I do this, the resulting video contains the images upside down and Red and Blue channels swapped. The code is simple as:

Code: Select all

		
BYTE * pData;
pSample->GetPointer(&pData); //pSample is IMediaSample
img.read((LPCTSTR)CurrentFile);
img.crop(Geometry(CropSettings.width , CropSettings.height,CropSettings.xoff , CropSettings.yoff ));
img.unsharpmask(UnsharpSettings.radius , UnsharpSettings.sigma , UnsharpSettings.amount , UnsharpSettings.threshold );
MagickCore::PixelPacket *pp = img.getPixels (0,0,img.columns (),img.rows());
img.writePixels(MagickCore::RGBQuantum,pData);

The original bmp file is OK. When I write it back with img.write(), the result is also OK. When I open the imagefile without imagemagick, and put the bitmap data into pData, the AVI file is correct, too. (But I don't want to save the image after imagemagick operations, and open it again, the filter must be fast as possible.)
Maybe something simple, I might missed something. I'm a C# programmer, but with this DS filter I have to use c++. So I'm not too experienced with c++, I can't figure it out, why. I can only think because of writepixels().

Thanks for suggestions

Re: Writepixels() gives me BGR upside-down image

Posted: 2009-01-23T07:38:31-07:00
by magick
Do you want RGBQuantum or should it be BGRQuantum? Right after your unsharp, add
  • img.flip();
See if that fixes the problem. If that works you can instead create scanline loop and grab pixels from the bottom to the top:

Code: Select all

  for (int y=image->rows-1; y >= 0; y--)
    img.getPixels (0,y,img.columns (),1);
    ...

Re: Writepixels() gives me BGR upside-down image

Posted: 2009-01-23T09:17:45-07:00
by jpuskas
Thanks, I forgot to mention, yes, I did img.flip() and it rotates the image back in the right direction, but my really problem is the color change: the red channel info (data) appears in the blue channel and reverse (RGB->BGR), but of course the AVI writer "sees" BGR as RGB, so the colors are wrong. The flip doesn't help with it. The reason why I didn't mention the flip, that I think maybe these two problems has the same source.
I hope there's a solution for this color channel mixing, I wouldn't be happy to write a function to put the color bytes back to the right place. That's why you would use this kind of tools like imagemagick.

Re: Writepixels() gives me BGR upside-down image

Posted: 2009-01-23T10:08:59-07:00
by magick
Did you try MagickCore::BGRQuantum? It should reverse the red and blue channels for you.

Re: Writepixels() gives me BGR upside-down image

Posted: 2009-01-23T10:38:59-07:00
by jpuskas
Thanks for the tip. I have Imagemagick 6.4.8, but when I change to this

Code: Select all

img.writePixels(MagickCore::BGRQuantum,pImagebuffer);
I got an error message : error C2039: 'BGRQuantum' : is not a member of 'MagickCore'.

I don't know why. :? Should it be there?

Re: Writepixels() gives me BGR upside-down image

Posted: 2009-01-23T13:03:43-07:00
by magick
Well what do you know. We don't have support for BGRQuantum after all. We'll get that into the next point release. In the mean-time you can use write():
  • void Magick::Image::write ( const int x_,
    const int y_,
    const unsigned int columns_,
    const unsigned int rows_,
    const std::string &map_,
    const StorageType type_,
    void *pixels_ )

where the map is "BGR" and the the type is MagickCore::CharPixel.

Re: Writepixels() gives me BGR upside-down image

Posted: 2009-01-24T06:29:19-07:00
by jpuskas
Yes, this works now.
But I don't get it, what was the point suggesting BGRQuantum, if you doesn't support it yet?

Thanks for help.