PDA

View Full Version : Displaying a QImage through pixels and QGraphicsView



strateng
23rd March 2010, 04:52
Hey guys,

I was wondering if anyone could help me with a problem regarding to QImage and QGraphicsView. I currently used coding to create the image through QImage from a tutorial on Trolltech. The problem I am having is that I am uncertain if I'm getting the right image displayed since the image is just several dots when I try running the code. Is this incorrect? If it is correct, is there a way to enlarge the pixels shown in the image?





QImage image(3, 3, QImage::Format_Indexed8);
QRgb value;

value = qRgb(122, 163, 39); // 0xff7aa327
image.setColor(0, value);

value = qRgb(237, 187, 51); // 0xffedba31
image.setColor(1, value);

value = qRgb(189, 149, 39); // 0xffbd9527
image.setColor(2, value);

image.setPixel(0, 1, 0);
image.setPixel(1, 0, 0);
image.setPixel(1, 1, 2);
image.setPixel(2, 1, 1);

QGraphicsScene *scene = new QGraphicsScene (this);
QPixmap pixmap = QPixmap::fromImage(image);
scene->addPixmap(pixmap);
delete QGraphicsViewscene();
QGraphicsView.setScene(scene);



Thanks,
Strateng

JohannesMunk
23rd March 2010, 11:24
The image you are creating is 3pixels x 3pixels big.. what do you expect?

what do you do in delete QGraphicsViewscene(); ?? Usually you only setup your scene once. And delete/add items to it.

Is this related to your other posting regarding OpenGL? You can set the QGraphicsView to use an OpenGL Viewport.
Qt will then automatically draw your image with OpenGL.. no need for drawpixels..

Joh

JohannesMunk
24th March 2010, 17:06
My last post somehow didn't register as post to the thread..

strateng
24th March 2010, 23:14
Hey,

Thanks for your reply. The two threads are linked somewhat but I was wondering in particular in this thread if there was a way to zoom in to check if the pixels are the correct colour. The main problem i seem to be having is that when I increase the width and height of the QImage to 300 by 300, I get an image of the first pixel. I thank the delete QGraphicsViewScene is just to erase any previous set scene so that it changes when you want to add a new scene. There seems to be an error with this line since when I copied it over a part was cut off.

Thanks,
Strateng


The image you are creating is 3pixels x 3pixels big.. what do you expect?

what do you do in delete QGraphicsViewscene(); ?? Usually you only setup your scene once. And delete/add items to it.

Is this related to your other posting regarding OpenGL? You can set the QGraphicsView to use an OpenGL Viewport.
Qt will then automatically draw your image with OpenGL.. no need for drawpixels..

Joh

JohannesMunk
24th March 2010, 23:17
Don't delete the scene. Thats very wrong! You set it up, once! Look at the QGraphicsView examples.

You need to initalize the pixmap. You can't just make it bigger..

HIH

Johannes

strateng
24th March 2010, 23:21
Hey,

Line 21 should be:

delete QGraphicsViewscene.scene();

instead of

delete QGraphicsViewscene();

Thanks,
Strateng

strateng
24th March 2010, 23:25
Hey,

Sorry I'm a little confused by this. Did you mean don't delete the actual QGraphicsScene? Cause if so there was an error when I copied the code over from QT. When you mentioned initalizing the pixmap, I am not sure what you meant exactly by that. Can you explain that a little further?

Thanks,
Strateng

JohannesMunk
24th March 2010, 23:54
Ok.. I have coded a litte example:



project file:

TARGET = imgloader
TEMPLATE = app
SOURCES += main.cpp

main.cpp

#include <QApplication>
#include <QtGui>
#include <QtCore>

class MainForm : public QWidget
{ Q_OBJECT
public:
MainForm() {
scene = new QGraphicsScene();
view = new QGraphicsView(scene);
QHBoxLayout* hl = new QHBoxLayout();
QPushButton* loadimg_pb = new QPushButton("Load Image(s) ..");
connect(loadimg_pb,SIGNAL(clicked()),this,SLOT(Loa dImages()));
hl->addWidget(loadimg_pb,0);
hl->addStretch(1);
QVBoxLayout* vl = new QVBoxLayout();
vl->addWidget(view);
vl->addLayout(hl);
setLayout(vl);
}
protected slots:
void LoadImages() {
QStringList filenames = QFileDialog::getOpenFileNames(0, "Open Image", "", "Images (*.jpg;*.jpeg;*.bmp;*.png)");
for (int i=0;i<filenames.length();++i)
{
QImage img(filenames.at(i));
if (!img.isNull()) {
QGraphicsPixmapItem* pi = scene->addPixmap(QPixmap::fromImage(img).scaledToWidth(50 ));
pi->setFlag(QGraphicsItem::ItemIsMovable,true);
pi->setFlag(QGraphicsItem::ItemIsSelectable,true);
pi->setPos(qrand()*500/RAND_MAX,qrand()*500/RAND_MAX);
}
}
}

private:
QGraphicsScene* scene;
QGraphicsView* view;
};

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));

MainForm form;
form.setGeometry(100,100,800,600);
form.show();

return app.exec();
}

#include "main.moc"
You can see.. the scene and view are setup only once.. afterwards items are added..

QPixmap setup: You need to define a color value for each pixel. In your code example you are using indexed colors. Thats why they first setup the 3 colors and then set the values of the pixels.. But this has nothing to do with your graphicsscene but with QPixmap setup.. In the example above I simply load the pixmap from file..

What do you want to show?

Johannes

strateng
25th March 2010, 00:11
Hey,

I'm just wondering though with the setup you're doing. The image will only be loading once right? Therefore your program would crash if you tried to load another image? I'm trying to show a QImage made up of pixels only on to QGraphicsScene.

Thanks,
Strateng

JohannesMunk
25th March 2010, 00:15
No.. It can load lots of items. Each time you click the button.. an image is created and added to the scene. Compile it and see for yourself!

What pixels? What do you want to show? I didn't want to create a random image.. so I just loaded them from file..

Any further questions?

Johannes

JohannesMunk
25th March 2010, 00:19
I didn't store any reference to the images, though.. Maybe thats what made you wonder. The local scope of the variable img doesn't hurt here, because it gets deep copied when I add it to the scene and thats before it gets destroyed.

Johannes

strateng
25th March 2010, 00:22
Hey,

Just wondering though what do you mean by added to the scene? Does that mean the scene automatically updates and moves to the next image? Oh the pixel section is fine but would you be able to write a little example of connecting a QImage thats been converted to OpenGL to be viewed on QGraphicsView?

Thanks,
Strateng

JohannesMunk
25th March 2010, 00:47
Just try to run the example! You would see, that it doesn't move to the next image, but it shows them all.. The item is added to the scene, the scene updates automatically, like you said, and all images are shown.

As for OpenGL. You just call view->setViewPort(new QGLWidget()) and everything is drawn using OpenGL!



pro:
QT += opengl
TARGET = listclass
TEMPLATE = app
SOURCES += main.cpp

main.cpp:
#include <QApplication>
#include <QDebug>
#include <QtGui>
#include <QtCore>
#include <QtOpenGL>

class MainForm : public QWidget
{ Q_OBJECT
public:
MainForm() {
scene = new QGraphicsScene();
view = new QGraphicsView(scene);
view->setViewport(new QGLWidget());

QPushButton* loadimg_pb = new QPushButton("Load Image(s) ..");
connect(loadimg_pb,SIGNAL(clicked()),this,SLOT(Loa dImages()));
QPushButton* testimg_pb = new QPushButton("Test Image!");
connect(testimg_pb,SIGNAL(clicked()),this,SLOT(Tes tImage()));

QHBoxLayout* hl = new QHBoxLayout();
hl->addWidget(loadimg_pb,0);
hl->addWidget(testimg_pb,0);
hl->addStretch(1);
QVBoxLayout* vl = new QVBoxLayout();
vl->addWidget(view);
vl->addLayout(hl);
setLayout(vl);
}
protected slots:
void LoadImages() {
QStringList filenames = QFileDialog::getOpenFileNames(0, "Open Image", "", "Images (*.jpg;*.jpeg;*.bmp;*.png)");
for (int i=0;i<filenames.length();++i)
{
QImage img(filenames.at(i));
if (!img.isNull()) {
QGraphicsPixmapItem* pi = scene->addPixmap(QPixmap::fromImage(img).scaledToWidth(50 ));
pi->setFlag(QGraphicsItem::ItemIsMovable,true);
pi->setFlag(QGraphicsItem::ItemIsSelectable,true);
pi->setPos(qrand()*500/RAND_MAX,qrand()*500/RAND_MAX);
}
}
}
void TestImage() {
QImage image(300, 300, QImage::Format_Indexed8);
// Setup the color palette for indexed colormode
QRgb value;
value = qRgb(122, 163, 39); // 0xff7aa327
image.setColor(0, value);
value = qRgb(237, 187, 51); // 0xffedba31
image.setColor(1, value);
value = qRgb(189, 149, 39); // 0xffbd9527
image.setColor(2, value);
// Set pixels
for (int x=0;x<300;++x) {
for (int y=0;y<150;++y) {
image.setPixel(x, y, 0);
}
}
for (int x=0;x<150;++x) {
for (int y=150;y<300;++y) {
image.setPixel(x, y, 2);
}
}
for (int x=150;x<300;++x) {
for (int y=150;y<300;++y) {
image.setPixel(x, y, 1);
}
}
QGraphicsPixmapItem* pi = scene->addPixmap(QPixmap::fromImage(image));
pi->setFlag(QGraphicsItem::ItemIsMovable,true);
pi->setFlag(QGraphicsItem::ItemIsSelectable,true);
pi->setPos(qrand()*500/RAND_MAX,qrand()*500/RAND_MAX);
}

private:
QGraphicsScene* scene;
QGraphicsView* view;
QGLWidget* glwidget;
};

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));

MainForm form;
form.setGeometry(100,100,800,600);
form.show();

return app.exec();
}

#include "main.moc"

JohannesMunk
25th March 2010, 01:03
Aah! The Qt Pixmap example, misses some pixels! You have to initialize the whole image with fill before.. if you want to avoid a crash :->



void TestImage2() {
QImage image(3,3, QImage::Format_Indexed8);
// Setup the color palette for indexed colormode
QRgb value;
value = qRgb(122, 163, 39); // 0xff7aa327
image.setColor(0, value);
value = qRgb(237, 187, 51); // 0xffedba31
image.setColor(1, value);
value = qRgb(189, 149, 39); // 0xffbd9527
image.setColor(2, value);
value = qRgb(240, 240, 240); // light gray..
image.setColor(3, value);
// Initialize the whole image
image.fill(3);
// Set pixels
image.setPixel(0, 1, 0);
image.setPixel(1, 0, 0);
image.setPixel(1, 1, 2);
image.setPixel(2, 1, 1);
QGraphicsPixmapItem* pi = scene->addPixmap(QPixmap::fromImage(image).scaledToWidth( 50));
pi->setFlag(QGraphicsItem::ItemIsMovable,true);
pi->setFlag(QGraphicsItem::ItemIsSelectable,true);
pi->setPos(qrand()*500/RAND_MAX,qrand()*500/RAND_MAX);
}
Now you have two options to scale your pixmap, to see if the colors are right :->

Johannes

strateng
25th March 2010, 01:13
Hey,

Thanks I think you have answered all the questions I currently have. I'll get back to you if there are any other questions on the topic.

Thanks,
Strateng

JohannesMunk
25th March 2010, 01:23
Great! Good night, then!

Johannes

strateng
29th March 2010, 07:05
Hey,

I attempted using OpenGL to draw the pixel images with the following code



QGraphicsView,setViewPort(new QGLWidget())


However I was given the following error when I attempted to run the program:

WARNING: Application calling GLX 1.3 function "glXCreatePixmap" when GLX 1.3 is not supported! This is an application bug!
failed to create drawable

Can anyone help me with this problem?

Thanks,
Strateng