Qt-interest Archive, May 2007
Image composition
Message 1 in thread
Hello,
I'm trying to create a color image with two other color images. Both of these source images would be converted in gray levels, one would be put in a green channel and the other in a red channel. The goal is to have a final image with yellow pixels where where yellow pixels were image corresponds. Does anyone have an idea how to do this in a simple way ?


Message 2 in thread
Tib wrote:
> Hello,
> I'm trying to create a color image with two other color images. Both
> of these source images would be converted in gray levels, one would be
> put in a green channel and the other in a red channel. The goal is to
> have a final image with yellow pixels where where yellow pixels were
> image corresponds. Does anyone have an idea how to do this in a simple way ?
You can use a QImage to put whatever pixel data you want in each of the RGBA channels of it. How you encode your source
images to create the new image is largely non-Qt specific.
--st
--
[ signature omitted ]
Message 3 in thread
Hello, I tried this example
http://doc.trolltech.com/4.2/qpainter.html#composition-modes, but doesn't
work for my images (actually jpg images with green objects on black
background)
What I want is simply convert my images to grayscale, get values for each
(thus 2D matrix width x height with intensities between 0 & 255), and
construct a new one with each matrix in a different channel, but actually
with the documentation on QImage and QPixmap, I don't see a straightforward
manner to do that..
Does someone have a quick method for this purpose ?
----- Original Message -----
From: "Stathis" <stathis@xxxxxxxxxxxxxxxx>
To: <qt-interest@xxxxxxxxxxxxx>
Sent: Wednesday, May 23, 2007 3:49 PM
Subject: Re: Image composition
> Tib wrote:
>> Hello,
>> I'm trying to create a color image with two other color images. Both
>> of these source images would be converted in gray levels, one would be
>> put in a green channel and the other in a red channel. The goal is to
>> have a final image with yellow pixels where where yellow pixels were
>> image corresponds. Does anyone have an idea how to do this in a simple
>> way ?
>
> You can use a QImage to put whatever pixel data you want in each of the
> RGBA channels of it. How you encode your source
> images to create the new image is largely non-Qt specific.
>
> --st
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
--
[ signature omitted ]
Message 4 in thread
Tib schrieb:
> ...
> What I want is simply convert my images to grayscale, get values for
> each (thus 2D matrix width x height with intensities between 0 & 255),
> and construct a new one with each matrix in a different channel, but
> actually with the documentation on QImage and QPixmap, I don't see a
> straightforward manner to do that..
> Does someone have a quick method for this purpose ?
You can always do the bit-fiddling yourself, you get access to the RGB
data in QImage for example with:
uchar * QImage::scanLine ( int i )
(Read the Qt docs about the RGB format:
"Warning: If you are accessing 32-bpp image data, cast the returned
pointer to QRgb* (QRgb has a 32-bit size) and use it to read/write the
pixel value. You cannot use the uchar* pointer directly, because the
pixel format depends on the byte order on the underlying platform. Use
qRed(), qGreen(), qBlue(), and qAlpha() to access the pixels."
Now do a bit of byte-shifting, construct a new QRgb value (given your
"red"- and "green"-grayscale images) and write this into your new QImage
(don't forget to allocate space in the new QImage with the appropriate
c'tor, for example QImage ( int width, int height, Format format )).
Cheers, Oliver
--
[ signature omitted ]
Message 5 in thread
On 5/24/07, Till Oliver Knoll <oliver.knoll@xxxxxxxxxxx> wrote:
> "Warning: If you are accessing 32-bpp image data, cast the returned
> pointer to QRgb* (QRgb has a 32-bit size) and use it to read/write the
> pixel value. You cannot use the uchar* pointer directly, because the
> pixel format depends on the byte order on the underlying platform. Use
> qRed(), qGreen(), qBlue(), and qAlpha() to access the pixels."
this is only for reading the pixels. If you want to update the value
... for this I use following structure:
class ARGB {
public:
union {
unsigned int argb;
struct {
#ifdef WORDS_BIGENDIAN
//If it is big endian machine
unsigned char a;
unsigned char r;
unsigned char g;
unsigned char b;
#else
//If it is little endian machine
unsigned char b;
unsigned char g;
unsigned char r;
unsigned char a;
#endif
};
};
/*
... there are some operators and other stuff defined here, which I left out.
.. Actually, the class is template class and can work with both 32
<unsigned char> and 64bit <unsigned short> pixels, but I have
simplified it for posting here.
I can send full class if interested
*/
};
and cast the data to ARGB*. WORDS_BIGENDIAN is defined/not defined in
./configure.
This way you can access the components more conveniently.
Example:
pixel[i].r=pixel[i].r/2; ///Halve the red component
This may break on some mixed-endian machines or maybe some exotic
configurations, but I am not sure whether Qt can run on any of these
anyway :)
> Now do a bit of byte-shifting, construct a new QRgb value (given your
> "red"- and "green"-grayscale images) and write this into your new QImage
> (don't forget to allocate space in the new QImage with the appropriate
> c'tor, for example QImage ( int width, int height, Format format )).
--
[ signature omitted ]
Message 6 in thread
BH schrieb:
>> ....
>> pointer to QRgb* (QRgb has a 32-bit size) and use it to read/write the
^^^^^^^^^^
>> ...
> this is only for reading the pixels. If you want to update the value
The documentation sais otherwise. In fact, why in your opinion would the
following not work:
QImage result (32, 32, QImage::Format_ARGB32);
// get the first pixel of the 6th line
QRgb pixel = (QRgb *)result.scanline(5);
// set this pixel to red
pixel = qRgba (255, 0, 0, 255);
In my opinion this should render the first pixel of the 6th scanline to
red, independent on the underlying byte-order (qRgba takes care of
this). No?
Cheers, Oliver
--
[ signature omitted ]
Message 7 in thread
> The documentation sais otherwise. In fact, why in your opinion would
the
> following not work:
>
> QImage result (32, 32, QImage::Format_ARGB32);
>
> // get the first pixel of the 6th line
> QRgb pixel = (QRgb *)result.scanline(5);
>
> // set this pixel to red
> pixel = qRgba (255, 0, 0, 255);
>
> In my opinion this should render the first pixel of the 6th scanline
to
> red, independent on the underlying byte-order (qRgba takes care of
> this). No?
On the other hand his example looks rather clumsy in "plain Qt":
pixel[i].r=pixel[i].r/2; ///Halve the red component
pixel[i] = qRgba(qRed(pixel[i])/2, qGreen(pixel[i]), qBlue(pixel[i]),
qAlpha(pixel[i]));
qRed() etc. should return references and all would be good ;)
Cheers,
Peter
--
[ signature omitted ]
Message 8 in thread
Thats what I meant. You CAN update the components, but only by
re-creating entire pixel with updated values.
So thing like:
pixel[i] = qRgba(qRed(pixel[i])/2, qGreen(pixel[i]), qBlue(pixel[i]),
qAlpha(pixel[i]));
will internally decompose (since these functions are inline) into
something like this:
pixel[i]=
(((pixel[i] >>16) & 0xff)/2 & 0xff) << 16)
| ((pixel[i]>>8) & 0xff) & 0xff) << 8)
| ((pixel[i] & 0xff) & 0xff)
| (((pixel[i] >> 24) & 0xff) & 0xff) << 24)
That is lot of basically useless instructions and if you do it in a
loop .... then the resulting code may be a bit slow.
Martin Petricek
> > The documentation sais otherwise. In fact, why in your opinion would
> the
> > following not work:
...
> On the other hand his example looks rather clumsy in "plain Qt":
>
> pixel[i].r=pixel[i].r/2; ///Halve the red component
>
> pixel[i] = qRgba(qRed(pixel[i])/2, qGreen(pixel[i]), qBlue(pixel[i]),
> qAlpha(pixel[i]));
>
> qRed() etc. should return references and all would be good ;)
>
> Cheers,
> Peter
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
--
[ signature omitted ]
Message 9 in thread
BH schrieb:
> Thats what I meant. You CAN update the components, but only by
> re-creating entire pixel with updated values.
I completely agree on that :) If you really want to modify only parts of
the colour (e.g. the red value) in an efficient way then you have to do
the bit-fiddling yourself, taking care of endianess issues, just as
you've shown in your example code.
Cheers, Oliver
--
[ signature omitted ]
Message 10 in thread
In a little different way for my image superposition, I'm trying to find how
to make an image transparent. I think it can be done in few lines without
setting alpha value for every pixels, no ? Found some elements in qt list
archive but doesn't work yet. My image is in
QImage::Format_ARGB32_Premultiplied.
Does someone know how to do it easily ? Just wanna set transparency for
first image in order to put it on second image..
----- Original Message -----
From: "Till Oliver Knoll" <oliver.knoll@xxxxxxxxxxx>
To: "Qt Interest List" <qt-interest@xxxxxxxxxxxxx>
Sent: Friday, May 25, 2007 10:59 AM
Subject: [OT] Re: Image composition
> BH schrieb:
>> Thats what I meant. You CAN update the components, but only by
>> re-creating entire pixel with updated values.
>
> I completely agree on that :) If you really want to modify only parts of
> the colour (e.g. the red value) in an efficient way then you have to do
> the bit-fiddling yourself, taking care of endianess issues, just as you've
> shown in your example code.
>
> Cheers, Oliver
>
>
>
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
--
[ signature omitted ]
Message 11 in thread
Hello,
according to the advices given, I got a result which is what I visually
want. http://tiboufroulou.com/prog/superposition.png
I want to display a window in which two images are superposed, 3 sliders
allow to set a translation and a rotation of one of the two images, in order
to find the best values for which the two images match. These 3 values will
be initialization values for my 3D registration algorithm.
Here is the code:
QRgb *scanLineSource01=0, *scanLineSource02=0, *scanLineDest=0;
for (int ligne = 0; ligne < imageSource02.width(); ++ligne) {
scanLineSource01 = (QRgb *)imageSource01.scanLine(ligne);
scanLineSource02 = (QRgb *)imageSource02.scanLine(ligne);
scanLineDest = (QRgb *)superpositionImages.scanLine(ligne);
for (int x = 0; x < imageSource01.height(); ++x) {
// image 1 shift in reds and add image 2
scanLineDest[x] =
qRgb(qGreen(scanLineSource01[x]),0,0)+scanLineSource02[x];
}
}
Now, applying rotation or/and translation to a source images and calculating
the superposed image seems a little bit painful, the tranformed() function
doesn't work as I would, 'cause the "transformation matrix is internally
adjusted to compensate for unwanted translation", dixit Qt doc.
In an another way, I tried to adapt the image composition example
(http://doc.trolltech.com/4.3/painting-imagecomposition.html) but I can't
find a way to set the transparency of the top image like under photoshop
(which leads to the same result as Qt above code)
..any idea ? Do I have to calculate myself pixels translations and rotations
of top image and construct the final images or is there an easiest way to do
all that stuff.. ?
Any idea GREATLY appreciated !! :))
--
[ signature omitted ]
Message 12 in thread
Hi,
Tib wrote:
> Now, applying rotation or/and translation to a source images and
> calculating
> the superposed image seems a little bit painful, the tranformed()
> function doesn't work as I would, 'cause the "transformation matrix is
> internally adjusted to compensate for unwanted translation", dixit Qt doc.
Attached is a simple example of how to make a rotated image using QImage
and QMatrix. This example has some issues i.e. uses setPixel() and
pixel() and so is not the fastest, and it makes no attempt to
interpolate (hence the periodic black dots in the image). As a QMatrix
is used, any transform can be achieved.
Hopefully what it does show is that modifying image data according to an
arbitrary transform can be straight forward.
Tim
#include <iostream>
#include <QImage>
#include <QPixmap>
#include <QSlider>
#include <QLabel>
#include <QHBoxLayout>
#include <QWidget>
#include <QApplication>
#include <QMatrix>
#include <QDebug>
class ImageModifier : public QObject
{
Q_OBJECT
public:
ImageModifier( const QImage& im, QObject* parent = NULL )
: QObject( parent ),
in_( im )
{}
public slots:
void setRotate( int r )
{
qDebug() << "setRotate:" << r;
matrix_ = QMatrix();
matrix_.translate( in_.width()/2, in_.height()/2 );
matrix_.rotate( r );
matrix_.translate( -in_.width()/2, -in_.height()/2 );
apply();
}
signals:
void updated( const QPixmap& );
private:
void apply()
{
if ( out_.size() != in_.size() )
out_ = in_;
out_.fill( 0 );
const int width = in_.width();
const int height = in_.height();
int w_, h_;
int count = 0;
for ( int h = 0; h<height; ++h )
for ( int w = 0; w<width; ++w )
{
matrix_.map( w, h, &w_, &h_ );
if ( w_ < 0 || w_ >= width ) continue;
if ( h_ < 0 || h_ >= height ) continue;
++count;
out_.setPixel( w_, h_, in_.pixel( w, h ) );
}
qDebug() << 100.0*count/(width*height) << "%";
p_ = QPixmap::fromImage( out_ );
emit updated( p_ );
}
QMatrix matrix_;
QImage in_;
QImage out_;
QPixmap p_;
};
#include "ImageRotate.moc"
int main( int argc, char* argv[] )
{
QApplication app( argc, argv );
if ( argc != 2 )
{
std::cout << argv[0] << " <image filename>\n";
return 0;
}
QWidget* t = new QWidget();
QHBoxLayout* layout = new QHBoxLayout( t );
QLabel* l = new QLabel( t );
layout->addWidget( l );
QSlider* s = new QSlider( t );
s->setMinimum( -180 );
s->setMaximum( 180 );
layout->addWidget( s );
t->show();
ImageModifier modifier = ImageModifier( QImage( argv[1] ) );
l->connect( &modifier, SIGNAL( updated( const QPixmap& ) ), SLOT( setPixmap( const QPixmap& ) ) );
modifier.connect( s, SIGNAL( valueChanged( int ) ), SLOT( setRotate( int ) ) );
modifier.setRotate( 0 );
app.exec();
}
Message 13 in thread
have a look at the image composition chapter in the qt docs.
http://doc.trolltech.com/4.2/qpainter.html#composition-modes
there is even an extensive sample application there.
Cheers,
Peter
> Hello,
> I'm trying to create a color image with two other color images.
Both
> of these source images would be converted in gray levels, one would be
put
> in a green channel and the other in a red channel. The goal is to have
a
> final image with yellow pixels where where yellow pixels were image
> corresponds. Does anyone have an idea how to do this in a simple way ?
--
[ signature omitted ]