Xcoupe : coupe 2d

Description

Ce programme permet de visualiser la coupe 2D d'une image vue de haut en fonction de la luminosité.
Plus le point est lumineux, plus il est considéré comme haut, et plus il est sombre, plus il est considéré comme bas.

Le fonctionnement est simple, on balade un trait à l'endroit où l'on souhaite que la coupe soit réalisée, et celle-ci est faite sur la droite automatiquement. Pour cela le programme prend tous les points de l'image sur cette ligne, totatise les valeurs RGB chaque pixel, et par un petit produit en croix, l'affiche dans un label.

Source / Exemple :


// La partie principale du programme :

#include "CoupeGeol.hpp" 

CoupeGeol::CoupeGeol()
{
	QApplication::setStyle(new QPlastiqueStyle);
	
	wFirstImageLabel = new QLabel (this);
	wNewImageLabel = new QLabel (this);	
	
	wOpenFileButton = new QPushButton (tr ("Ouvrir une image"));	
		wOpenFileButton->setStyleSheet ( "QPushButton { border: 2px solid #8e9dff;"
		"border-radius: 6px; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #7F94C4, 

stop: 1 #6479A9); color : rgb(204,204,255)}");
		connect(wOpenFileButton, SIGNAL (clicked()), this, SLOT (OpenFile()));		
	wSaveButton = new QPushButton (tr ("Enregistrer la coupe"));
		wSaveButton->setEnabled(false);
		wSaveButton->setStyleSheet ( "QPushButton { border: 2px solid #FF9D8E;"
		"border-radius: 6px; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #C4947F, 

stop: 1 #A97964); color : rgb(204,204,255)}");
	connect(wSaveButton, SIGNAL (clicked()), this, SLOT (Save()));
	
	wFirstResLabel = new QLabel(this);		
	wFirstResLabel->setText("Resolution -> Largeur : 0 , Hauteur : 0");
	wFirstResLabel->setMaximumHeight(35);
	wNewResLabel = new QLabel(this);
	wNewResLabel->setText("Largeur : 0 , Hauteur : 0");		
	wNewResLabel->setMaximumHeight(35);
	wLine = new QSlider(this);	
		wLine->setOrientation(Qt::Vertical);
		wLine->setMinimum(0);		
		wLine->setMaximum(100);	
		wLine->setValue(50);	
		wLine->setEnabled(false);		
		wLine->setStyleSheet ( "QSlider { border: 2px solid #FF9D8E;"
		"border-radius: 6px; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #C4947F, 

stop: 1 #A97964); color : rgb(204,204,255)}");

	QObject::connect(wLine, SIGNAL(valueChanged(int)), this, SLOT(DrawLine()));
	
	
	wOrganizationLayout = new QGridLayout (this);
	wOrganizationLayout->addWidget(wLine,0,0);
	wOrganizationLayout->addWidget(wFirstImageLabel,0,1);
	wOrganizationLayout->addWidget(wNewImageLabel, 0,2);	
	wOrganizationLayout->addWidget (wOpenFileButton,1,1);
	wOrganizationLayout->addWidget(wSaveButton,1,2);	
	wOrganizationLayout->addWidget(wFirstResLabel,2,1);
	wOrganizationLayout->addWidget(wNewResLabel, 2,2);	

	wCentralWidget = new QWidget (this);	
	wCentralWidget->setLayout  (wOrganizationLayout);
	
	setCentralWidget (wCentralWidget);
	setWindowTitle (tr("XCoupe"));
	setWindowState (Qt::WindowMaximized);	

	nbProcess = 0;
	setPalette(QColor(0,0,50));
	setWindowIcon(QIcon("Icone.png"));

	 
}

CoupeGeol::~CoupeGeol()
{

}

void
CoupeGeol::DrawLine()
{
	
	
	int height = wFirstImage.height();
	int width = wFirstImage.width();

	
	int nH = ((100 - wLine->value()) * height / 100);

	wLastImage = wFirstImage;	
	
	for (int x = 0; x < width; x++)
	{
		for (int y = nH - 2 ; y < nH + 2; y++)
		{
			if (y >= 0 && y < height)
			{
				wLastImage.setPixel(x, y, qRgba(255,0,0,255)); 
			}
		}

	}
	

	wFirstImageLabel->setPixmap(QPixmap::fromImage(wLastImage).scaled(wFirstImageLabel->width(), 

wFirstImageLabel->height(),Qt::KeepAspectRatio));

	CoupeGeol::Processing();
}

void
CoupeGeol::OpenFile()
{
	QString fileName = QFileDialog::getOpenFileName(this, "Ouvrir une image", QString(), "Images (*.png *.gif 

  • .jpg *.jpeg *.bmp)");
if (!fileName.isEmpty()) { wSaveButton->setEnabled (true); wLine->setEnabled(true); wFirstImage.load(fileName); wFirstImageLabel->setPixmap(QPixmap::fromImage(wFirstImage).scaled(wFirstImageLabel->width(), wFirstImageLabel->height(),Qt::KeepAspectRatio)); wFirstResLabel->setText ("Largeur : " + QString::number(wFirstImage.width()) + " , Hauteur : " + QString::number(wFirstImage.height())); wLastImage = wFirstImage; DrawLine(); } } void CoupeGeol::Processing() { int height = wFirstImage.height(); int width = wFirstImage.width(); wNewImage = QImage(width, height, wFirstImage.format()); for (int y = 0; y < height;y++) { for (int x = 0; x < width; x++) { wNewImage.setPixel(x,y, qRgba(255,255,255,255)); } } int pHL = ((100 - wLine->value()) * height / 100); for (int x = 0; x < width; x++) { QColor color = wFirstImage.pixel(x,pHL); int sum = color.red() + color.green() + color.blue(); int ref = 3 * 255; int pY = ref - ((sum * height) / ref); for (int y = pY-2; y < pY + 2; y++) { wNewImage.setPixel(x, y, qRgba(125,125,255,255)); } } bool traverse = false; for (int x = 0; x < width; x++) { for (int y = 0; y < height;y++) { QColor color = wNewImage.pixel(x,y); if (color.red() == 125 && color.green() == 125 && color.blue() == 255 && color.alpha() == 255) { traverse = true; } if (traverse == true && color.red() == 255 && color.green() == 255 && color.blue() == 255 && color.alpha() == 255) { wNewImage.setPixel(x,y, qRgba(120,120,120,255)); } } traverse = false; } wNewResLabel->setText ("Largeur : " + QString::number(wNewImage.width()) + " , Hauteur : " + QString::number(wNewImage.height())); wNewImageLabel->setPixmap(QPixmap::fromImage(wNewImage).scaled(wNewImageLabel->width(), wNewImageLabel->height(),Qt::KeepAspectRatio)); nbProcess ++; } void CoupeGeol::Save() { QString filtre; QString chemin = QFileDialog::getSaveFileName(this, "Enregistrer la coupe", QString(), "Fichier image(*.bmp *.jpg
  • .png)", &filtre);
wNewImage.save(QString(chemin), 0, 90); }

Conclusion :


Reste à automatiser les dimensions de la fenêtre, et à permettre le changement de couleur pour la coupe, mais cette version permet déjà d'enregistrer l'image de rendu.

Le programme est dans le zip sous le nom de XCoupe.ex_, avec un exemple.

N'hésitez pas à laisser vos commentaires.

Codes Sources

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.