0

I'm programming in C++ on Qt Creator, with a CImagePPM class allowing to manipulate images in PPM format (opening, rotations, etc).

I have a problem when opening an image file (the strat.ppm file located in the project directory), with the opening error message ("Impossible to open the file!").

The opening is handled by the CImagePPM constructor.

Here is the code of CImagePPM.h :

#ifndef CIMAGEPPM_H
#define CIMAGEPPM_H
 
#include <iostream>
#include <fstream>
#include <QPainter>
#include <string>
 
using namespace std;
 
struct rgb
{
    int r,g,b;
};
 
class CImagePPM
{
public:
    CImagePPM();
    CImagePPM(string nomfich);
    ~CImagePPM();
    void dessiner(QPainter * p);
    void rot90Droite();
 
private:
    int largeur;
    int hauteur;
    int intensiteMax;
    rgb** pixels;
};
 
#endif

And that of CImagePPM.cpp :

#include "cimageppm.h"
#include <fstream>
 
CImagePPM::CImagePPM()
{
    largeur=200;
    hauteur=100;
    intensiteMax=255;
    pixels=new rgb*[hauteur];
    for (int i=0;i<hauteur;i++) {
        pixels[i]=new rgb[largeur];
        pixels[i]->r=0;
        pixels[i]->g=0;
        pixels[i]->b=0;
    }
}
 
 
CImagePPM::CImagePPM(string nomfich) {
    ifstream fichier(nomfich.c_str(), ios::in);
    string temp;
 
    if (!fichier.fail()) {
        fichier >> temp;
        fichier >> this->largeur;
        fichier >> this->hauteur;
        fichier >> this->intensiteMax;
        pixels=new rgb*[this->hauteur];
        for (int i=0;i<hauteur;i++) {
            pixels=new rgb*[this->largeur];
            for (int j=0;j<largeur;j++) {
                fichier >> this->pixels[i][j].r >> this->pixels[i][j].g >> this->pixels[i][j].b;
        }
        fichier.close();
        }
    }
    else cerr << "Impossible d'ouvrir le fichier!" << endl;
 
}
 
CImagePPM::~CImagePPM() {
    for (int i=0;i<hauteur;i++) {
        delete pixels[i];
    }
}
 
void CImagePPM::dessiner(QPainter * p) {
    for (int i=0;i<hauteur;i++) {
        for (int j=0;j<largeur;j++) {
            p->setPen(QColor(pixels[i][j].r,pixels[i][j].g,pixels[i][j].b));
            p->drawPoint(j,i);
        }
    }
}

And finally mainwindow.cpp :

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "cimageppm.h"
 
 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    img=new CImagePPM();
    CImagePPM img("strat.ppm");
}
 
MainWindow::~MainWindow()
{
    delete ui;
    delete img;
}
 
 
void MainWindow::paintEvent(QPaintEvent* e) {
    QWidget::paintEvent(e);
    QPainter painter(this);
 
    if (img!=NULL) {
        img->dessiner(&painter);
        }
    }

Update : When I put the file in the build directory, it crashes.

Update 2 : I corrected the lines as below and it no longer crashes. The file is loaded properly but the image is a black rectangle with the correct size.

pixels=new rgb*[this->hauteur];
        for (int i=0;i<hauteur;i++) {
            pixels[i]=new rgb[this->largeur];
            for (int j=0;j<largeur;j++) {
                fichier >> pixels[i][j].r >> pixels[i][j].g >> pixels[i][j].b;
        }

Update 3 : I moved the file to the build directory and corrected a mistake in the constructor (the file was closed too soon) and the image shows.

drownman
  • 1
  • 2
  • Maybe your file `strat.ppm` is in the wrong folder. – drescherjm Jan 04 '22 at 19:00
  • It is in the project directory – drownman Jan 04 '22 at 19:02
  • `CImagePPM img("strat.ppm");` creates a new local variable named `img` that has its lifetime end when the constructor for `MainWindow` is finished. – drescherjm Jan 04 '22 at 19:09
  • `img=new CImagePPM();` looks like it uses a `img` which is a member variable of the MainWindow class. – drescherjm Jan 04 '22 at 19:10
  • `strat.ppm` should be in the build directory, not the project directory. – m7913d Jan 04 '22 at 19:37
  • 1
    Please try to create a [mcve], i.e. remove all the irrelevant parts of the example. Basically, your problem is `ifstream ("strat.ppm", ios::in).fail() == true`. – m7913d Jan 04 '22 at 19:40
  • Off topic: please read ["Why is "using namespace std;" considered bad practice?"](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). And it should *never* be used in a header file. – G.M. Jan 04 '22 at 19:49
  • 1
    ***When I put the file in the build directory, it crashes. I created a minimal reproducible example and it still crashes.*** That is a different behavior than you had when the file could not be read. Qt-creator has a built in debugger. You need to use it to understand what your program is doing. – drescherjm Jan 04 '22 at 20:52

1 Answers1

0

Part of your problem is that Qt Creator (which I presume you're using for your IDE) doesn't use the project directory as the current working directory when it runs.

If you have Foo/Foo.pro, then you'll get a weird directory in ../build... that is the build directory, and that's your current working directory when you run from within Qt. And Qt / qmake won't copy your image file into the build directory, so when you try to open it, it won't be there.

But it looks like someone tried it for you -- getting it all set up -- and things still crash when the file is found. But using the debugger should help you get further.

What you might want to do is print out the current working directory from within main().

Joseph Larson
  • 8,530
  • 1
  • 19
  • 36
  • 1
    Moving the file to the build directory helped to load correctly the file. The problem now is that the image black, despite having the correct size. – drownman Jan 04 '22 at 21:57
  • It's black because you don't initialize it anywhere. As already said above `CImagePPM img("strat.ppm");` simply creates a local variable without doing anything do you `ìmg` member variable - c++ basics. – chehrlic Jan 05 '22 at 17:01