PDA

View Full Version : QImage Rotation and Translation & Invert Specific Colors



2lights
14th August 2013, 09:19
Good Day,

Part 1 of 2
Im superimposing 2 images(Overlaying images, with the 2nd image having a 50% opacity)

Now I have a rotation angle, a Row Offset & Column Offset Value.

When I rotate the 2nd image... it works
When a call the TRANSLATE function nothing happens!

Overlay Images Function:


primaryImage.load(imageFileName1);

secondaryImage.load(imageFileName2);
secondaryImage.invertPixels(); //Inverting Grayscale Image

QTransform rotating;
rotating.rotate(RotationAngle);
secondaryImage = secondaryImage.transformed(rotating); // Works
QTransform translating;
translating.translate(RowOffset, ColOffset);
secondaryImage = secondaryImage.transformed(translating); // Does not work

paintScreen = true;
update();

:confused:

this is what I got:


//Paint Function
if(paintScreen = true){

//Repaint Primary Image
painter.drawImage(QPoint(0, 0), primaryImage);
painter.setOpacity(0.5);// drawn at n% opacity
painter.drawImage(QPoint(0, 0), secondaryImage); }


Ideas Please
Solutions welcome


Part 2 of 2
Also Instead of inverting colors of 2nd image(grayscale)
Is there a way to convert the whole image into like a "Red Scale" or any other color of different shades

Solution
Kind Regards

karankumar1609
14th August 2013, 10:09
reference from THIS (http://qt-project.org/faq/answer/how_can_i_convert_a_colored_qpixmap_into_a_graysca led_qpixmap)



#include <QtGui>

int main(int argc, char** argv)
{
QApplication app(argc, argv);
QPixmap pixmap("logo.png");
QImage image = pixmap.toImage();
QRgb col;
int gray;
int width = pixmap.width();
int height = pixmap.height();
for (int i = 0; i < width; ++i)
{
for (int j = 0; j < height; ++j)
{
col = image.pixel(i, j);
gray = qGray(col);
image.setPixel(i, j, qRgb(gray, gray, gray));
}
}
pixmap = pixmap.fromImage(image);
QLabel label;
label.setPixmap(pixmap);
label.show();
return app.exec();
}



following example convert the image into an gray scale image.
HERE:

gray = qGray(col);
convert the QRgb color set into a gray color.
You can use QRed, QBlue etc. according to your need.

2lights
14th August 2013, 10:29
Part 1 of 2
Any ideas

Part 2 of 2
Tried it, this is what i get
No compile error, But nothing happens no change to color
Though
I get this debug output err:
QImage:: pixel: coordinate (320,478) out of range
QImage:: setPixel: coordinate (320,478) out of range
QImage:: pixel: coordinate (320,479) out of range
...



void Compare::OverLayImages()
{
primaryImage.load(imageFileName1);

QRgb colour;
int newCol;
int width = primaryImage.width();
int height = primaryImage.height();

for(int i = 0; i <= width; ++i)
{
for (int j = 0; j <= height; ++j)
{
colour = primaryImage.pixel(i, j);
newCol = qRed(colour);
primaryImage.setPixel(i, j, qRgb(newCol, newCol, newCol));
}
}

karankumar1609
14th August 2013, 10:51
for(int i = 0; i <= width; ++i)

for (int j = 0; j <= height; ++j)
Loop should be i < width, and j < height.

mentioned code should work. may be you are doing it differently.
Where do you use this primaryImage?

Have you tried Image Composition Example (http://harmattan-dev.nokia.com/docs/library/html/qt4/painting-imagecomposition.html)

2lights
14th August 2013, 11:38
i < width, and j < height.
Same problem
QImage::setPixel: Index -16645630 out of range
QImage::setPixel: Index -16645630 out of range
....
Nothing happens

Part of my program requires me to paint the image in a label
Could that be the problem... I doubt it thiugh because the editing takes place before the paint function is called

paint function


painter.setWindow(QRect(0,0,totalWidth,totalHeight ));
update();

//Repaint Primary Image
painter.drawImage(QPoint(0, 0), primaryImage);


painting no problem...
color is the issue!

& Any ideas on the translation of image

wysota
14th August 2013, 11:54
When a call the TRANSLATE function nothing happens!
That's correct, translating an image will have no effect. The result of calling transformed() is a new image that can encompass the whole original image after applying a transformation to it. When rotating an image, the new resulting image will be larger and will contain all the contents or the original image. When translating, the new image will have the same size as the original one and will contain the whole original image -- which is identical to the original image.


this is what I got:


//Paint Function
if(paintScreen = true){

//Repaint Primary Image
painter.drawImage(QPoint(0, 0), primaryImage);
painter.setOpacity(0.5);// drawn at n% opacity
painter.drawImage(QPoint(0, 0), secondaryImage); }


That's very easy:

painter.drawImage(0, 0, primaryImage);
painter.setOpacity(0.5);
painter.drawImage(colShift, rowShift, secondaryImage);
You can do the same with rotation, by the way:


painter.drawImage(..., ..., primaryImage);
painter.save();
painter.translate(primaryImage.width()/2, primaryImage.height()/2);
painter.rotate(45);
painter.drawImage(..., ..., secondaryImage);
painter.restore();


Is there a way to convert the whole image into like a "Red Scale" or any other color of different shades
Sure, iterate over all pixels and change their color in any way you want.

karankumar1609
14th August 2013, 12:03
You require to set a result image on QLabel..
The better way to do this, is have a result image and paint on it (Outside the paint event).
After loading of primaryImage and secondaryImage you can do your calculations on images and create a result image



void ImageComposer::recalculateResult()
{
QPainter::CompositionMode mode = currentMode();

QPainter painter(&resultImage);
painter.setCompositionMode(QPainter::CompositionMo de_Source);
painter.fillRect(resultImage.rect(), Qt::transparent);
painter.setCompositionMode(QPainter::CompositionMo de_SourceOver);
painter.drawImage(0, 0, destinationImage);
painter.setCompositionMode(mode);
painter.drawImage(0, 0, sourceImage);
painter.setCompositionMode(QPainter::CompositionMo de_DestinationOver);
painter.fillRect(resultImage.rect(), Qt::white);
painter.end();

resultLabel->setPixmap(QPixmap::fromImage(resultImage));
}


the above code is the part of the Image Composition Example (http://harmattan-dev.nokia.com/docs/library/html/qt4/painting-imagecomposition.html)

As per your program need you have to look at the Image Composition Example (http://harmattan-dev.nokia.com/docs/library/html/qt4/painting-imagecomposition.html)

2lights
14th August 2013, 12:50
Getting there...

Remember, the image im loading is grayscale
Im converting it to Red/Green or Blue scale

I tried for testing purposes only,
I uploaded a color image...
the ConvertColor Function
instead of converting everyting to red(different shades of red), it made it black & white
but no "Index out of range error"

When I upload a grayscale image(program needs to do)
I get an Index out of range err in application output


QImage::setPixel: Index -16645630 out of range
QImage::setPixel: Index -16645630 out of range
QImage::setPixel: Index -16645630 out of range
QImage::setPixel: Index -16514044 out of range
QFSFileEngine::open: No file name specified

In the label the original image(grayscale image) is uploadded
no change in color



primaryImage.load(imageFileName1);

QRgb colour;
int newCol;
int width = primaryImage.width();
int height = primaryImage.height();

for(int i = 0; i < width; ++i)
{
for (int j = 0; j < height; ++j)
{
colour = primaryImage.pixel(i, j);
newCol = qRed(colour);
primaryImage.setPixel(i, j, qRgb(newCol, newCol, newCol));
}
}


Im not seeing the problem, :confused:
Solution?

Translation SOLVED.... Thanks:)

karankumar1609
14th August 2013, 13:27
I tried for testing purposes only,
I uploaded a color image...
the ConvertColor Function
instead of converting everyting to red(different shades of red), it made it black & white
but no "Index out of range error"

Your grayscale image might be of different format.
Load it in QImage::Format_RGB32 and then use the same function. it will solve your index out of range problem.

try:


...
primaryImage.load(imageFileName1);
primaryImage = primaryImage.convertToFormat(QImage::Format_RGB32) ;
...

wysota
14th August 2013, 13:29
Remember, the image im loading is grayscale
If the image is originally grayscale then it is likely that it is indexed and if so, changing colours of the image can be simplified to modify just the color table.

E.g. to convert your image to shades of red, you'd do:


QImage img(...);
QVector<QRgb> colorTable = img.colorTable();
for(int i=0;i<colorTable.size();++i) {
colorTable[i] = qRed(qGray(colorTable[i]));
}
img.setColorTable(colorTable);

Note -- the image has to be indexed and not true color!

2lights
14th August 2013, 13:48
I created an if statement to check if grayscale.
image1.AllGray();

if(false)
@karankumar1609
That did solve the out of scope issue
though No Colour change on image :confused:

if(true){
@wysota
implemented wysota solution
Unfortunately, No Image is displayed at all :confused:
}

It seemed simple at first,
But now im just hitting barriers

Just to reiterate my problem
(Most of images are black and white and shades of gray)
and convert entire image to a shade of green, red or blue

Where am i going wrong?

karankumar1609
14th August 2013, 13:56
well the above example should work for you.,
Please paste your code for more clarification on what exactly you are doing.

wysota
14th August 2013, 13:56
Did you check if the image was indexed prior to implementing my solution?

2lights
14th August 2013, 14:06
Not sure if im checking if image is indexed correctly
this is what i got: an if statement around your solution


if(image1.allGray()){ //if grayscale than it should be indexed... I think
QVector<QRgb> colorTable = image1.colorTable();
for(int i=0;i<colorTable.size();++i) {
colorTable[i] = qRed(qGray(colorTable[i]));
}

No image is shown

karankumar1609
14th August 2013, 14:11
Implement this


...
...
image1.setColorTable(colorTable);

you just calculate the color table but u need to se the new color table to image1.

2lights
14th August 2013, 14:20
I am setting the color table after the loop

This is my current function to load image


void Compare::getImageFileName1()
{
fp1 = true;
QFileDialog dialog(this, "Upload");
dialog.setNameFilter(tr("Images (*.png *.xpm *.jpg *.bmp *.tif)"));
dialog.setViewMode(QFileDialog::Detail);

if(dialog.exec())
{
imageFileName1 = dialog.selectedFiles().first();
}

image1.load(imageFileName1);
image1Width = image1.width();
image1Height = image1.height();

if(image1.allGray()){
QVector<QRgb> colorTable = image1.colorTable();
for(int i=0;i<colorTable.size();++i) {
colorTable[i] = qRed(qGray(colorTable[i]));
}
image1.setColorTable(colorTable);
}
imageDrawFlag1 = true;
}


In my paint function:


//Painting actual Image
if(imageDrawFlag1 == true){
painter.drawImage(QPoint(0, 0), image1);


Your time & help is much appreciated

karankumar1609
14th August 2013, 14:30
code is correct, it exactly do what you write.
Well its my assumption you should call update(), may be your paint function not called after returning from the function.



void Compare::getImageFileName1()
{
fp1 = true;
QFileDialog dialog(this, "Upload");
dialog.setNameFilter(tr("Images (*.png *.xpm *.jpg *.bmp *.tif)"));
dialog.setViewMode(QFileDialog::Detail);

if(dialog.exec())
{
imageFileName1 = dialog.selectedFiles().first();
}

image1.load(imageFileName1);
image1Width = image1.width();
image1Height = image1.height();

if(image1.allGray()){
QVector<QRgb> colorTable = image1.colorTable();
for(int i=0;i<colorTable.size();++i) {
colorTable[i] = qRed(qGray(colorTable[i]));
}
image1.setColorTable(colorTable);
}
imageDrawFlag1 = true;

update();
}

wysota
14th August 2013, 15:16
Not sure if im checking if image is indexed correctly
Do you understand what an "indexed" image is? allGray() will not tell you if an image is indexed or not.

2lights
14th August 2013, 15:48
Not sure what an indexed image is...
But the images that i will be loading will be grayscale images
& will have ext: .png *.xpm *.jpg *.bmp *.tif

I tried loading
Image is not uploaded

Maybe the image is being uploaded but the entire image is converted to the color gray!
hence it looks like no image is uploaded

I added


image1.convertToFormat(QImage::Format_Mono); // if not grayscale converting to grayscale




QVector<QRgb> colorTable = image1.colorTable();
for(int i=0;i<colorTable.size();++i)
{
colorTable[i] = qRed(qGray(colorTable[i]));
}
image1.setColorTable(colorTable);


got rid of the iff statement

:(

wysota
14th August 2013, 18:52
Not sure what an indexed image is...
Go to QImage docs, press Ctrl+F or equivalent and type in "indexed".

Apart from that read this: http://en.wikipedia.org/wiki/Indexed_color

2lights
15th August 2013, 09:11
...
...
...
...