Marcos con croma Qt Designer

Iniciado por alvarogt91, 6 Junio 2014, 20:20 PM

0 Miembros y 1 Visitante están viendo este tema.

alvarogt91

Hola! tengo un problema a la hora de manejar un complemento de mi programa de croma.
El programa consiste en cargar una imagen de fondo, un marco con croma (zona en verde puro) y manejar una serie de sliders horizontales y verticales a modo de zoom para situar la imagen de fondo dentro del marco como nos interesa.

El caso es que a la hora de manejar el zoom puedo aumentar la escala de la imagen, pero no disminuirla.

ENUNCIADO:
En este ejercicio vamos a realizar un programa para componer imágenes usando el efecto croma. En concreto, el usuario podrá cargar en la aplicación dos imágenes, una foto y un marco, donde el marco vendrá preparado con la zona del croma en verde puro:Claro está, las imágenes no tienen la misma resolución y la zona de la cara no tiene por qué coincidir con la del croma en el marco. Por ello, la aplicación contendrá los controles para trasladar la imagen en horizontal y vertical o escalarla:
La imagen de trabajo de la aplicación será de 800x600 píxeles. La imagen de marco se debe escalar con esas proporciones, mientras que las proporciones de la foto vendrán ajustadas por el usuario. Como vemos, el programa debe ser capaz de componer las dos imágenes, colocando una sobre otra en función de la posición determinada por el usuario y sustituyendo los píxeles verdes del marco por los de la foto.
El menú principal contendrá un submenú fichero, con el que podremos cargar las imágenes (foto y marco), grabar en disco la composición actual o salir y un submenú About que mostrará el nombre de los autores de la práctica.
Como vemos, la posición y escala de la foto se maneja con sliders y un botón central para restaurar escala y posición a sus valores predeterminados.
Junto con el enunciado de la práctica se adjuntan distintos archivos con los recursos necesarios (iconos, marcos y fotos). Para crear tus propios marcos y fotos, se recomienda el formato bmp y una resolución no mayor de 800x600. En general, se debe usar un formato sin compresión para que el color del croma sea lo más puro posible.
Código (cpp) [Seleccionar]

----------------------------------------------------------------------------------------------
<mainwindow.ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
 <property name="geometry">
  <rect>
   <x>0</x>
   <y>0</y>
   <width>613</width>
   <height>432</height>
  </rect>
 </property>
 <property name="mouseTracking">
  <bool>false</bool>
 </property>
 <property name="windowTitle">
  <string>Aplicacion de Marcos</string>
 </property>
 <property name="windowIcon">
  <iconset resource="resources.qrc">
   <normaloff>:/etiquetas/Material ejercicio 2/Crystal_Clear_app_neotux.png</normaloff>:/etiquetas/Material ejercicio 2/Crystal_Clear_app_neotux.png</iconset>
 </property>
 <widget class="QWidget" name="centralWidget">
  <widget class="QLabel" name="label_3">
   <property name="geometry">
    <rect>
     <x>150</x>
     <y>10</y>
     <width>451</width>
     <height>341</height>
    </rect>
   </property>
   <property name="text">
    <string/>
   </property>
   <property name="scaledContents">
    <bool>false</bool>
   </property>
  </widget>
  <widget class="QWidget" name="layoutWidget">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>10</y>
     <width>131</width>
     <height>193</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_2">
    <item>
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <widget class="QLabel" name="label">
        <property name="text">
         <string>Colocación imagen</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QSlider" name="horizontalSlider">
        <property name="minimum">
         <number>1</number>
        </property>
        <property name="maximum">
         <number>100</number>
        </property>
        <property name="sliderPosition">
         <number>50</number>
        </property>
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout_2">
      <property name="sizeConstraint">
       <enum>QLayout::SetNoConstraint</enum>
      </property>
      <item>
       <widget class="QSlider" name="verticalSlider">
        <property name="minimum">
         <number>1</number>
        </property>
        <property name="maximum">
         <number>100</number>
        </property>
        <property name="sliderPosition">
         <number>50</number>
        </property>
        <property name="orientation">
         <enum>Qt::Vertical</enum>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="pushButton">
        <property name="enabled">
         <bool>true</bool>
        </property>
        <property name="autoFillBackground">
         <bool>false</bool>
        </property>
        <property name="text">
         <string/>
        </property>
        <property name="icon">
         <iconset resource="resources.qrc">
          <normaloff>:/etiquetas/Material ejercicio 2/Quick_restart.png</normaloff>:/etiquetas/Material ejercicio 2/Quick_restart.png</iconset>
        </property>
        <property name="iconSize">
         <size>
          <width>50</width>
          <height>50</height>
         </size>
        </property>
        <property name="flat">
         <bool>false</bool>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <widget class="QLabel" name="label_2">
        <property name="text">
         <string>Escala</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QSlider" name="horizontalSlider_2">
        <property name="minimum">
         <number>1</number>
        </property>
        <property name="maximum">
         <number>10</number>
        </property>
        <property name="singleStep">
         <number>1</number>
        </property>
        <property name="pageStep">
         <number>1</number>
        </property>
        <property name="value">
         <number>5</number>
        </property>
        <property name="sliderPosition">
         <number>5</number>
        </property>
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
       </widget>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
 </widget>
 <widget class="QMenuBar" name="menuBar">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>613</width>
    <height>21</height>
   </rect>
  </property>
  <widget class="QMenu" name="menuFichero">
   <property name="title">
    <string>Fichero</string>
   </property>
   <addaction name="actionCargar"/>
   <addaction name="actionGrabar_en_el_disco"/>
   <addaction name="actionSalir"/>
  </widget>
  <widget class="QMenu" name="menuAcerca_de">
   <property name="title">
    <string>Acerca de...</string>
   </property>
  </widget>
  <addaction name="menuFichero"/>
  <addaction name="menuAcerca_de"/>
 </widget>
 <widget class="QToolBar" name="mainToolBar">
  <attribute name="toolBarArea">
   <enum>TopToolBarArea</enum>
  </attribute>
  <attribute name="toolBarBreak">
   <bool>false</bool>
  </attribute>
  <addaction name="actionCargar"/>
  <addaction name="actionGrabar_en_el_disco"/>
  <addaction name="actionSalir"/>
  <addaction name="actionAcerca_de"/>
 </widget>
 <widget class="QStatusBar" name="statusBar"/>
 <action name="actionCargar">
  <property name="icon">
   <iconset resource="resources.qrc">
    <normaloff>:/etiquetas/Material ejercicio 2/Crystal_Clear_action_db_comit.png</normaloff>:/etiquetas/Material ejercicio 2/Crystal_Clear_action_db_comit.png</iconset>
  </property>
  <property name="text">
   <string>Cargar imagenes...</string>
  </property>
 </action>
 <action name="actionGrabar_en_el_disco">
  <property name="icon">
   <iconset resource="resources.qrc">
    <normaloff>:/etiquetas/Material ejercicio 2/Crystal_Clear_device_floppy_unmount.png</normaloff>:/etiquetas/Material ejercicio 2/Crystal_Clear_device_floppy_unmount.png</iconset>
  </property>
  <property name="text">
   <string>Grabar en el disco</string>
  </property>
 </action>
 <action name="actionSalir">
  <property name="icon">
   <iconset resource="resources.qrc">
    <normaloff>:/etiquetas/Material ejercicio 2/Crystal_Clear_action_exit.png</normaloff>:/etiquetas/Material ejercicio 2/Crystal_Clear_action_exit.png</iconset>
  </property>
  <property name="text">
   <string>Salir</string>
  </property>
 </action>
 <action name="actionAcerca_de">
  <property name="checkable">
   <bool>false</bool>
  </property>
  <property name="checked">
   <bool>false</bool>
  </property>
  <property name="enabled">
   <bool>true</bool>
  </property>
  <property name="icon">
   <iconset resource="resources.qrc">
    <normaloff>:/etiquetas/Material ejercicio 2/Crystal_Clear_app_neotux.png</normaloff>:/etiquetas/Material ejercicio 2/Crystal_Clear_app_neotux.png</iconset>
  </property>
  <property name="text">
   <string>Acerca de</string>
  </property>
  <property name="autoRepeat">
   <bool>true</bool>
  </property>
  <property name="visible">
   <bool>true</bool>
  </property>
  <property name="iconVisibleInMenu">
   <bool>false</bool>
  </property>
 </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
 <include location="resources.qrc"/>
</resources>
<connections/>
</ui>

-----------------------------------------------------------------------------------------------
<mainwindow.ui>
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
//para seleccionar origen de archivo a abrir
#include <QFileDialog>
//para cargar imagenes y proporciones
#include <QPixmap>
//para ver cantidades de color
#include <QColor>
//para transparencias de foto
#include <QPainter>

#include <iostream>//libreria pruebas
using namespace std;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
   Q_OBJECT

public:
   explicit MainWindow(QWidget *parent = 0);
   ~MainWindow();

private slots:
   void on_horizontalSlider_valueChanged(int value);
   void on_verticalSlider_valueChanged(int value);
   void on_horizontalSlider_2_sliderMoved(int position);
   void on_actionSalir_triggered();
   void on_actionAcerca_de_triggered();
   void croma();
   void on_pushButton_clicked();
   void on_actionCargar_triggered();
   //void rellenarimagen();

private:
   Ui::MainWindow *ui;
   QFile file;

   QPixmap Img,nuevo,nuevo2,nuevo3,nuevo3copia,nuevocopia,nuevocopia2;
   //Img auxiliar para las escalas
   //nuevo,nuevo2 imagenes originales
   //nuevo3 nuestra resultante
   //nuevo3copia y nuevocopia cpoias con las que trabajar
   QImage imagen1,imagen2,resul,resulzoom;
   QRgb color;
   QPainter painter;
   int rojo,verde,azul;
   float proporcion,a,b;

};

#endif // MAINWINDOW_H
---------------------------------------------------------------------------------------------
<main.cpp>
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   MainWindow w;
   w.show();

   return a.exec();
}
---------------------------------------------------------------------------------------------
<mainwindow.cpp>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>


MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{//constructor defecto
   ui->setupUi(this);
}

MainWindow::~MainWindow()
{//destructor
   delete ui;
}
//croma
void MainWindow::croma(){
   for(int i=0;i<nuevo2.width();i++){
       for(int j=0;j<nuevo2.height();j++){
           color=imagen1.pixel(i,j);
           verde=qGreen(color);
           rojo= qRed(color);
           azul=qBlue(color);
           //no me sale de otra manera menos patatera
           if (verde==255&&azul<=30&&rojo<=30){
           }else{
               resul.setPixel(i,j,color);
           }
       }
   }
}

//cargamos el marco y la foto
void MainWindow::on_actionCargar_triggered()
{
       QMessageBox::information(NULL,"Cargando...","Imagen base","Aceptar");

       QString s = QFileDialog::getOpenFileName(this, "Cargar", NULL, "*.bmp");
       if(!s.isEmpty()) {
           Img.load(s);
       }

       if(!Img.isNull()) {
           nuevo = Img.scaled(451,341);//escalo la imagen
           ui->label_3->setPixmap(nuevo);
       }

       QMessageBox::information(NULL,"Cargando...","Marco","Aceptar");
       s = QFileDialog::getOpenFileName(this, "Cargar", NULL, "*.bmp");
       if(!s.isEmpty()) {
           Img.load(s);
       }
       if(!nuevo.isNull()){
           nuevo2 = Img.scaled(451,341);//escalo la imagen
           imagen1= nuevo2.toImage();
           //imagen copia a modificar
           resul=nuevo.toImage();
           croma();

       }
       nuevo3= QPixmap::fromImage(resul);
       ui->label_3->setPixmap(nuevo3);
}
//boton de reiniciar
void MainWindow::on_pushButton_clicked()
{
   ui->label_3->clear();
   ui->label_3->setPixmap(nuevo3);
}
//Acerca de
void MainWindow::on_actionAcerca_de_triggered()
{
   QMessageBox::information(NULL,"Creado por"," Alvaro","Aceptar");
}
//Salir del programa
void MainWindow::on_actionSalir_triggered()
{
   qApp->exit();
}
/*
//rellenar el resto de la imagen
void MainWindow::rellenarimagen(){
   nuevocopia=nuevo.scaled(a,b);
   imagen1=nuevocopia.toImage();
   nuevocopia2=QPixmap(451,341);
   nuevocopia2.fill(Qt::gray);
   resulzoom=nuevocopia2.toImage();
   for(int i=0;i<nuevocopia2.width();i++){
       for(int j=0;j<nuevocopia2.height();j++){
           color=imagen1.pixel(i,j);
           resulzoom.setPixel(i,j,color);
       }
   }
}*/
//barra horizontal para cambiar el zoom
void MainWindow::on_horizontalSlider_2_sliderMoved(int position)
{
   ui->label_3->clear();
   a=position*451*0.2;
   b=position*341*0.2;
   nuevocopia=nuevo.scaled(a,b);


   nuevocopia2=nuevocopia.copy(0,0,451,341);
   resul=nuevocopia2.toImage();
   for(int i=0;i<nuevo2.width();i++){
       for(int j=0;j<nuevo2.height();j++){
           color=imagen1.pixel(i,j);
           verde=qGreen(color);
           rojo= qRed(color);
           azul=qBlue(color);
           if (verde==255&&azul<=30&&rojo<=30){
           }else{
               resul.setPixel(i,j,color);
           }
       }
   }
   nuevo3copia= QPixmap::fromImage(resul);
   ui->label_3->setPixmap(nuevo3copia);
}

//desplazamiento vertical
void MainWindow::on_verticalSlider_valueChanged(int value)
{

}
//despalzamiento horizontal
void MainWindow::on_horizontalSlider_valueChanged(int value)
{
   for(int i=0;i<nuevo2.width();i++){
       for(int j=0;j<nuevo2.height();j++){
           color=imagen1.pixel(i,j);
           verde=qGreen(color);
           rojo= qRed(color);
           azul=qBlue(color);
           //no me sale de otra manera menos patatera
           if (verde==255&&azul<=30&&rojo<=30){
           }else{
               resul.setPixel(i,j,color);
           }
       }
   }
   //nuevo3copia.transformed();
}

eferion

Es mejor si cada archivo de código lo colocas en una etiqueta code diferente... si además a cada etiqueta de code le añades el lenguaje correspondiente, p.ej: code=cpp para C++, quedará todo mucho más legible.

No entiendo por qué usas tantas clases para las imágenes. A ver, tu partes de dos imagenes que tienes que fusionar ( imagen1 e imagen2 )... al fusionarlas vas a crear una tercera imagen ( imagenFusionada ) y esta ha de admitir zoom ... imagenFinal.

Tu estás usando 7 imágenes diferentes... te sobran 3.

Los pasos recomendados son los que te he comentado:

* Almacenas las dos imágenes originales en imagen1 e imagen2. (los nombres son orientativos).

* Fusionas las imagenes: imagenFusionada.

* Aplicas el zoom a la imagen fusionada: imagenFinal.

De esta forma:

* Si solo cambia el zoom, únicamente tienes que recalcular imagenFinal.

* Si cambias una de las dos imágenes originales tienes que calcular la fusionada y la imagen final.

La gracia de aplicar el zoom a la imagen fusionada y no al revés ( a diferencia de como tú lo haces ) es que cuando se amplía o se reduce el zoom, hay pixeles que se recalculan y pueden acabar teniendo un color que no se parezca en nada al de croma, por lo que la fusión posterior no va a funcionar.

Además al fusionar primero y hacer zoom después evitas tener que redimensionar dos imágenes... solo tienes que redimensionar una.

Por lo demás, saber si el pixel actual tiene color croma ( si no has redimensionado ) es tan sencillo como comparar colores:

Código (cpp) [Seleccionar]

QColor croma( 30, 30, 255 );

// ...

for(int i=0; i<imagen1.width(); i++)
{
  for(int j=0; j<imagen1.height(); j++)
  {
    color = imagen1.pixel( i ,j );
    if ( color == croma )
    {
    }
    else
    {
    }
  }
}