class exportSelectWidget(QWidget):
    def __init__(self):
        super().__init__()

        listExport = ['csv', 'json']

        self.comboBox = QComboBox(self)
        self.comboBox.setGeometry(50, 50, 400, 35)
        self.comboBox.addItems(listExport)

        self.btn = QPushButton('Next', self)
        self.btn.setGeometry(170, 120, 120, 35)
        self.btn.clicked.connect(self.select)

    def select(self):
        print((self.comboBox.currentText(), self.comboBox.currentIndex()))
        self.comboBox.close()
예제 #2
0
class GUI(QWidget):
    def __init__(self, rover_world, rover_config):
        """
        Constructor of the class
        Params: rover_world : object of type tmr_world.world
                rover_config: params of the tmr_rover.rover
        """

        super().__init__()

        self._title = 'TMR Control Panel'

        self._left = 0

        self._top = 0

        self._width = 800

        self._height = 540

        self._sensor_configs = [
            sensor.config() for sensor in rover_config['sensors']
        ]

        self._robot_config = rover_world._rover._robot.config()

        self.init_ui()

        self.init_pygame(rover_world)

    def init_ui(self):
        """
        Initialse basic Gui. It contains three buttons
        at hard coded locations. The locations of the buttons can be 
        made as a parameter, but since our gui is fixed in size
        it doesn't matter much. 
        """

        self.setWindowTitle(self._title)

        self.setGeometry(self._left, self._top, self._width, self._height)

        self._s_button = QPushButton('Configure Sensors', self)

        self._r_button = QPushButton('Configure Robot', self)

        self._v_button = QPushButton('Configure Visuals', self)

        self._s_button.move(540, 100)

        self._r_button.move(550, 200)

        self._v_button.move(550, 300)

        self._s_button.clicked.connect(partial(self.drop_down, 'edit'))

        self._r_button.clicked.connect(partial(self.pop_edit_up, None))

        self._v_button.clicked.connect(partial(self.drop_down, 'check'))

        self._move_check_box = QCheckBox("Self Move", self)

        self._log_check_box = QCheckBox("Print Log", self)

        self._log_check_box.move(550, 400)

        self._move_check_box.move(550, 450)

        self._move_check_box.setChecked(True)

        self._log_check_box.stateChanged.connect(self.update_log_status)

        self._move_check_box.stateChanged.connect(self.update_move_status)

        self.init_plot()

        self.show()

        self.show_initial_info()

    def init_plot(self):
        """
        Creates the plot window in the qt panel
        Plots only one value at a time.
        The value to be plotted can be chosen from the panel
        """

        self._frame = QFrame(self)

        self._frame.setStyleSheet("QWidget { background-color: %s }" %
                                  QColor(210, 210, 235, 255).name())

        self._layout = QGridLayout()

        self._plot_status = {}

        self._plot_defualt_idx = None

        for idx, config in enumerate(self._sensor_configs):

            if config['plotable_vals'] is not None:

                if self._plot_defualt_idx is None:

                    self._plot_defualt_idx = idx

                self._plot_status[idx] = [
                    False for _ in range(len(config['plotable_vals']))
                ]

        if self._plot_defualt_idx is not None:

            self._plot_status[self._plot_defualt_idx][0] = True

        self._frame.setLayout(self._layout)

        self._canvas = EmbedPlot()

        self._layout.addWidget(self._canvas, *(0, 1))

        # data_loop = threading.Thread(name = 'tmr_data_loop', target=self._canvas.data_receiver, daemon = True, args = (self.plot_data,))

        # data_loop.start()

    def show_initial_info(self):
        """
        A dialog box to give initial information
        on how to control the system.
        """

        msg = QMessageBox()

        msg.setIcon(QMessageBox.Information)

        msg.setText(
            "Use the arrow keys intermittently to move robot after selecting the rover window"
        )

        msg.setInformativeText("More info")

        msg.setWindowTitle("nfo")

        msg.setDetailedText(
            "The robot can be controlled by moving the system using arrow keys.\
            For this the Move Own check box on the gui should be turned off.\
            Make sure to press the keys intermittently. This is to enable constant movement without keyboard.\
            The sensor and the robot configuration can be changed via the configure buttons. The sensors available \
            for visualisation can be accessed via the visualise button. Only one parameter can be visualised per time."
        )

        msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)

        msg.exec_()

    def plot_data(self, d):
        """
        depending on how to plot
        plot only one value that is true
        """

        if self._plot_defualt_idx is not None:

            for idx, key in enumerate(
                    self._plot_status[self._plot_defualt_idx]):

                if self._plot_status[self._plot_defualt_idx][key]:

                    self._canvas.add_data(d[idx])

                    break

    def drop_down(self, form):
        """
        create a interactive drop down menu
        the input param is form which is of two types
        either edit type or check type
        """

        self._sensor_list = QComboBox(self)

        for idx, sensor in enumerate(self._sensor_configs):

            if form == 'edit':

                self._sensor_list.addItem(sensor['name'])

                self._sensor_list.activated[str].connect(
                    partial(self.pop_edit_up, idx))

                self._sensor_list.move(580, 150)

            elif form == 'check':

                if self.config_at_idx(idx)['plotable_vals'] is not None:

                    self._sensor_list.addItem(sensor['name'])

                    self._sensor_list.activated[str].connect(
                        partial(self.pop_check_up, idx))

                    self._sensor_list.move(580, 350)

        self._sensor_list.show()

    def pop_edit_up(self, sensor_idx):
        """
        The call back function to setup a edit type
        pop up. The input params are:
        Param: Sensor_idx :  integer denoting the index of the sensor
        """

        self._sensor_config = ConfigurePopup(self, 'edit', sensor_idx)

        self._sensor_config.move(self._width / 2, self._height / 2)

        self._sensor_config.show()

        if sensor_idx is not None:

            self._sensor_list.close()

    def pop_check_up(self, sensor_idx):
        """
        The call back function to setup a check type
        pop up. The input params are:
        Param: Sensor_idx :  integer denoting the index of the sensor
        """

        self._sensor_config = ConfigurePopup(self, 'check', sensor_idx)

        self._sensor_config.move(self._width / 2, self._height / 2)

        self._sensor_config.show()

        self._sensor_list.close()

    def robot_config(self):
        """
        Return the robot config file to the gui
        this is used for updation
        """

        return self._robot_config

    def config_at_idx(self, idx):
        """
        Return the sensor config to the gui
        if there are muliple sensors, the option
        is to the send the config at a particular index
        Params: idx: integer denoting the index of the sensor
        """

        return self._sensor_configs[idx]

    def update_configs(self, vals, idx):
        """
        This is the funciton that can be accessed
        via the gui to update the config parameters.
        Once called the corresponding sensor config dictionary
        is update using the vals provided.
        Params: vals : list of values having size equal to the dictionary params
                idx: integer denoting the index of the sensor
        """

        if idx is None:

            self._robot_config['params'].update({
                k: vals[i]
                for i, k in enumerate(self._robot_config['params'].keys())
            })

            self._rover_world.update_robot_config(self._robot_config)

        else:

            self._sensor_configs[idx]['params'].update({
                k: vals[i]
                for i, k in enumerate(self._sensor_configs[idx]
                                      ['params'].keys())
            })

            self._rover_world.update_sensor_config(self._sensor_configs[idx],
                                                   idx)

    def update_plots(self, vals, idx):
        """
        The function used to update the plots.
        Depending on which index of the sensor parameter is
        selected. Only one of the parameter can be plotted at a time.
        Params: vals: list of values having size equal to the plotable values
                idx: sensor index which has a plotable parameter
        """

        self._plot_status[idx] = vals

        self._plot_defualt_idx = idx

    def update_log_status(self, state):
        """
        Callback function from the check box in the panel.
        The input is the state of the q box. Based on the status
        the log will be either shown or turned off.
        """

        if state == Qt.Checked:

            self._rover_world.show_log(True)

        else:

            self._rover_world.show_log(False)

    def update_move_status(self, state):
        """
        Callback function from the check box in the panel.
        The input is the state of the q box. Based on the status
        the log will be either shown or turned off.
        """

        if state == Qt.Checked:

            self._rover_world.move_own(True)

        else:

            self._rover_world.move_own(False)

    def init_pygame(self, rover_world):
        """
        Initiate the pygame window loop
        Params: rover world of type tmr_world.world object
        """

        self._rover_world = rover_world

        self._timer = QTimer()

        self._timer.timeout.connect(self.pygame_loop)

        self._timer.start(0)

    def pygame_loop(self):
        """
        The pygmae loop to be run with the 
        qt window
        """

        if self._rover_world.run(self, self.plot_data):

            self.close()
예제 #3
0
class Filtros(QWidget):
	def __init__(self):
		super().__init__()

		self.title = "Filtros PDI by Jonayne."
		self.left = 10
		self.top = 10
		self.width = 1280
		self.height = 720
		self.initUI()

	#Iniciamos todos los elementos y los acomodamos.
	def initUI(self):
		self.setWindowTitle(self.title)
		self.setGeometry(self.left, self.top, self.width, self.height)

		self.line_edit_n = QLineEdit(self)
		self.line_edit_m = QLineEdit(self)

		self.line_edit_m.move(440, 694)
		self.line_edit_n.move(570, 694)
		self.line_edit_n.close()
		self.line_edit_m.close()

		self.lbl_mos = QLabel("Escriba la region deseada (n x m)", self)
		self.lbl_mos.move(450, 677)
		self.lbl_mos.close()

		self.colores_paquete = []
		self.imgs_paquete = []

		self.slider = QSlider(Qt.Horizontal, self)
		self.slider.setFocusPolicy(Qt.StrongFocus)
		self.slider.setTickPosition(QSlider.TicksBelow)
		self.slider.setTickInterval(10)
		self.slider.setSingleStep(1)
		self.slider.setGeometry(450, 690, 200, 20)
		self.slider.setMaximum(127)
		self.slider.setMinimum(-127)
		self.slider.setValue(0)

		self.lbl_bri = QLabel("Escoja la cantidad a aumentar o disminuir el brillo.", self)
		self.lbl_bri.move(450, 677)
		self.lbl_bri.close()
		self.slider.close()

		self.path_fotomosaico = None

		self.input = QLineEdit(self)
		self.input.move(540, 694)

		self.lbl_text = QLabel("Escriba el texto que quiera mostrar", self)
		self.lbl_text.move(450, 677)
		self.lbl_text.close()
		self.input.close()

		self.lbl_text_luz = QLabel("Escriba el peso (de 1 a 7)", self)
		self.lbl_text_luz.move(450, 677)
		self.lbl_text_luz.close()

		self.label_img_ori = QLabel(self)
		self.label_img_fil = QLabel(self)
		self.label_img_ori.setGeometry(QtCore.QRect(5, 28, 610, 650))
		self.label_img_fil.setGeometry(QtCore.QRect(630, 28, 610, 650))

		self.label_img_ori.setScaledContents(True)
		self.label_img_fil.setScaledContents(True)

		self.lbl_esco = QLabel("Escoja el filtro que quiere aplicar.", self)
		self.lbl_esco.move(25, 680)

		self.button_cargar = QPushButton('Cargar Imagen', self)
		self.button_cargar.setToolTip('Selecciona una imagen para editar.')
		self.button_cargar.move(1,1)

		self.button_cargar.clicked.connect(self.cargar_imagen)

		self.button_cargar_mos = QPushButton('Cargar conjunto de imagenes', self)
		self.button_cargar_mos.setToolTip('Selecciona una carpeta de imagenes.')
		self.button_cargar_mos.move(400,690)

		self.button_cargar_mos.clicked.connect(self.cargar_paquete)
		self.button_cargar_mos.close()

		self.colores_r = [(0,0,255), (255,255,255), (255,255,0), (0,128,0), (255,165,0), (255,0,0), (220,209,43), (220, 43, 220), (43, 49, 220), (149, 66, 50), (75, 49, 202), (6, 97, 12), (0, 0, 0), (176, 42, 225), (220, 43, 220), (42, 225, 200), (28, 37, 36), (84, 58, 64)]
		self.button_guardar = QPushButton('Guardar Imagen', self)
		self.button_guardar.setToolTip('Guarde la imagen con filtro aplicado.')
		self.button_guardar.move(150, 1)

		self.button_guardar.clicked.connect(self.guardar_imagen)

		self.button_aplicar = QPushButton('Aplicar...', self)
		self.button_aplicar.setToolTip('Aplique el filtro que escogio.')
		self.button_aplicar.move(230,690)

		self.filtro_escogido = ""
		self.num_colors_rubik = "256 colores" #rubik

		self.button_aplicar.clicked.connect(self.aplica_filtro)

		self.combo_rubik = QComboBox(self)
		self.combo_rubik.addItem("256 colores")
		self.combo_rubik.addItem("18 colores")
		self.combo_rubik.close()

		self.combo_rubik.activated[str].connect(self.onActivated_r) #rubik

		self.combo_rubik.move(400, 694)

		self.combo = QComboBox(self)

		# Lista de filtros.
		self.combo.addItem("Escoja un filtro")
		self.combo.addItem("Fotomosaico")
		self.combo.addItem("Random Dithering")
		self.combo.addItem("Rubik")
		self.combo.addItem("Recursiva /C")
		self.combo.addItem("Recursiva /T")				
		self.combo.addItem("Luz negra")		
		self.combo.addItem("AT&T")
		self.combo.addItem("Ecualizar imagen")
		self.combo.addItem("Semitonos A")
		self.combo.addItem("Semitonos B")
		self.combo.addItem("Semitonos C")
		self.combo.addItem("Quitar marca de agua")
		self.combo.addItem("Brillo")
		self.combo.addItem("Mosaico")
		self.combo.addItem("Inverso")
		self.combo.addItem("Alto contraste")
		self.combo.addItem("Blur")
		self.combo.addItem("Motion Blur")
		self.combo.addItem("Encontrar bordes")
		self.combo.addItem("Sharpen")
		self.combo.addItem("Emboss")
		self.combo.addItem("Mediana")
		self.combo.addItem("Letra a color")
		self.combo.addItem("Letra tono de gris")
		self.combo.addItem("Letras blanco y negro")
		self.combo.addItem("Letras en color")
		self.combo.addItem("Texto definido")
		self.combo.addItem("Naipes")
		self.combo.addItem("Domino")
		self.combo.addItem("Tono de gris 1")
		self.combo.addItem("Tono de gris 2")
		self.combo.addItem("Tono de gris 3")
		self.combo.addItem("Tono de gris 4")
		self.combo.addItem("Tono de gris 5")
		self.combo.addItem("Tono de gris 6")
		self.combo.addItem("Tono de gris 7")
		self.combo.addItem("Tono de gris 8")

		self.combo.move(25, 690)

		self.combo.activated[str].connect(self.onActivated)
		
		self.show()

	'''
		Metodo que carga una imagen en el programa y la muestra.
	'''
	@pyqtSlot()
	def cargar_imagen(self):
		try:
			image = QFileDialog.getOpenFileName(self,'Open File','~/')
			imagePath = image[0]
			self.pixmap_ori = QPixmap(imagePath).scaled(610, 650, Qt.KeepAspectRatio, Qt.SmoothTransformation) 
			self.pixmap_fil = QPixmap(imagePath).scaled(610, 650, Qt.KeepAspectRatio, Qt.SmoothTransformation)

			self.label_img_ori.setPixmap(self.pixmap_ori)

			#Para poder modificarla con PIL.
			self.pil_im_or = self.dame_img_PIL(imagePath)
			self.label_img_fil.setPixmap(QPixmap())
		except Exception:
			print("Error de lectura de archivo.")

	'''
		Metodo que carga un paquete de imagenes y obtiene informacion de ellas para el fotomosaico posterior.
	'''
	@pyqtSlot()
	def cargar_paquete(self):
		try:
			self.path_fotomosaico = QFileDialog.getOpenFileName(self, 'Open File', '~/', 'txt(*.txt)')
		except Exception:
			print("Error de lectura de archivo.")


	'''
		Metodo que guarda la imagen actual fitrada.
	'''
	@pyqtSlot()
	def guardar_imagen(self):
		try:
			options = QFileDialog.Options()
			options |= QFileDialog.DontUseNativeDialog
			file_name, _ = QFileDialog.getSaveFileName(self, "QFileDialog.getSaveFileName()","",'Solo en PNG (*.png)', options=options)
			if file_name:
				
				pixmap = self.pixmap_fil

				# Save QPixmap to QByteArray via QBuffer.
				byte_array = QByteArray()
				buffer = QBuffer(byte_array)
				buffer.open(QBuffer.ReadWrite)
				pixmap.save(buffer, Path(file_name).suffix[1:])

				with open(file_name, 'wb') as out_file:
					out_file.write(byte_array)

		except Exception:
			print("Error de lectura/escritura de archivo.")

	'''
		Metodo que cambia algunos Widgets al escoger un filtro en el combo.
	'''
	def onActivated(self, text):
		self.filtro_escogido = text
		self.button_aplicar.setText("Aplicar " + text)
		self.button_aplicar.adjustSize()
		if text == "Brillo":
			self.slider.show()
			self.lbl_bri.show()
			self.lbl_mos.close()
			self.line_edit_n.close()
			self.line_edit_m.close()
			self.lbl_text.close()
			self.input.close()
			self.lbl_text_luz.close()
			self.combo_rubik.close()
			self.button_cargar_mos.close()
		elif text == "Mosaico" or text == "Semitonos A" or text == "Semitonos A" or text == "Semitonos B" or text == "Semitonos C" or text == "Recursiva /C" or text == "Recursiva /T":
			self.lbl_mos.show()
			self.line_edit_n.show()
			self.line_edit_m.show()
			self.slider.close()
			self.lbl_bri.close()
			self.lbl_text.close()
			self.input.close()
			self.lbl_text_luz.close()
			self.combo_rubik.close()
			self.button_cargar_mos.close()
		elif text == "Texto definido":
			self.lbl_text.show()
			self.input.show()
			self.lbl_mos.close()
			self.line_edit_n.close()
			self.line_edit_m.close()
			self.slider.close()
			self.lbl_bri.close()
			self.lbl_text_luz.close()
			self.combo_rubik.close()
			self.button_cargar_mos.close()
		elif text == "Luz negra":
			self.lbl_text_luz.show()
			self.lbl_text.close()
			self.input.show()
			self.lbl_mos.close()
			self.line_edit_n.close()
			self.line_edit_m.close()
			self.slider.close()
			self.lbl_bri.close()
			self.combo_rubik.close()
			self.button_cargar_mos.close()
		elif text == "Rubik":
			self.lbl_text_luz.close()
			self.lbl_text.close()
			self.input.close()
			self.lbl_mos.close()
			self.line_edit_n.close()
			self.line_edit_m.close()
			self.slider.close()
			self.lbl_bri.close()
			self.combo_rubik.show()
			self.button_cargar_mos.close()
		elif text == "Fotomosaico":
			self.lbl_text_luz.close()
			self.lbl_text.close()
			self.input.close()
			self.lbl_mos.close()
			self.line_edit_n.close()
			self.line_edit_m.close()
			self.slider.close()
			self.lbl_bri.close()
			self.combo_rubik.close()
			self.button_cargar_mos.show()
		else:
			self.slider.close()
			self.lbl_bri.close()
			self.lbl_mos.close()
			self.line_edit_n.close()
			self.line_edit_m.close()
			self.lbl_text.close()
			self.input.close()
			self.lbl_text_luz.close()
			self.combo_rubik.close()
			self.button_cargar_mos.close()

	def onActivated_r(self, text): #rubik
		self.num_colors_rubik = text #rubik

	'''
		Metodo que segun un filtro fijado, lo aplica a la imagen cargada en el programa.
	'''
	@pyqtSlot()
	def aplica_filtro(self):
		#try:
		filtro = self.filtro_escogido
		if filtro != "":
			if filtro == "Tono de gris 1":
				img = self.tono_gris1(self.pil_im_or.copy())
			elif filtro == "Tono de gris 2":
				img = self.tono_gris2(self.pil_im_or.copy())
			elif filtro == "Tono de gris 3":
				img = self.tono_gris3(self.pil_im_or.copy())
			elif filtro == "Tono de gris 4":
				img = self.tono_gris4(self.pil_im_or.copy())
			elif filtro == "Tono de gris 5":
				img = self.tono_gris5(self.pil_im_or.copy())
			elif filtro == "Tono de gris 6":
				img = self.tono_gris6(self.pil_im_or.copy())
			elif filtro == "Tono de gris 7":
				img = self.tono_gris7(self.pil_im_or.copy())
			elif filtro == "Tono de gris 8":
				img = self.tono_gris8(self.pil_im_or.copy())
			elif filtro == "Brillo":
				img = self.brillo(self.pil_im_or.copy(), self.slider.value())
			elif filtro == "Mosaico":
				img = self.mosaico(self.pil_im_or.copy(), int(self.line_edit_n.text()), int(self.line_edit_m.text()))
			elif filtro == "Inverso":
				img = self.inverso(self.pil_im_or.copy())
			elif filtro == "Alto contraste":
				img = self.alto_contraste(self.pil_im_or.copy())
			elif filtro == "Blur":
				img = self.blur(self.pil_im_or.copy())
			elif filtro == "Motion Blur":
				img = self.motion_blur(self.pil_im_or.copy())
			elif filtro == "Encontrar bordes":
				img = self.edges(self.pil_im_or.copy())
			elif filtro == "Sharpen":
				img = self.sharpen(self.pil_im_or.copy())
			elif filtro == "Emboss":
				img = self.emboss(self.pil_im_or.copy())
			elif filtro == "Mediana":
				img = self.mediana(self.pil_im_or.copy())
			elif filtro == "Letra a color":
				img = self.letra_color(self.pil_im_or.copy())
			elif filtro == "Letra tono de gris":
				img = self.letra_tono_gris(self.pil_im_or.copy())
			elif filtro == "Letras blanco y negro":
				img = self.letras_bn(self.pil_im_or.copy())
			elif filtro == "Letras en color":
				img = self.letras_c(self.pil_im_or.copy())
			elif filtro == "Texto definido":
				img = self.texto_def(self.pil_im_or.copy(), self.input.text())
			elif filtro == "Naipes":
				img = self.naipes(self.pil_im_or.copy())
			elif filtro == "Domino":
				img = self.domino(self.pil_im_or.copy())
			elif filtro == "Quitar marca de agua":
				img = self.quitar_marca(self.pil_im_or.copy())
			elif filtro == "Ecualizar imagen":
				img = self.ecualizar_img(self.pil_im_or.copy())
			elif filtro == "Semitonos A":
				img = self.semitonosA(self.pil_im_or.copy(), int(self.line_edit_n.text()), int(self.line_edit_m.text()))
			elif filtro == "Semitonos B":
				img = self.semitonosB(self.pil_im_or.copy(), int(self.line_edit_n.text()), int(self.line_edit_m.text()))
			elif filtro == "Semitonos C":
				img = self.semitonosC(self.pil_im_or.copy(), int(self.line_edit_n.text()), int(self.line_edit_m.text()))
			elif filtro == "Luz negra":
				img = self.luz_negra(self.pil_im_or.copy(), int(self.input.text()))
			elif filtro == "AT&T":
				img = self.at_t(self.pil_im_or.copy())
			elif filtro == "Recursiva /C":
				img = self.recursiva_c(self.pil_im_or.copy(), int(self.line_edit_n.text()), int(self.line_edit_m.text()))
			elif filtro == "Recursiva /T":
				img = self.recursiva_b(self.pil_im_or.copy(), int(self.line_edit_n.text()), int(self.line_edit_m.text()))
			elif filtro == "Rubik":
				img = self.rubik(self.pil_im_or.copy(), self.num_colors_rubik)
			elif filtro == "Random Dithering":
				img = self.r_dithering(self.pil_im_or.copy())
			elif filtro == "Fotomosaico":
				img = self.fotomosaico(self.pil_im_or.copy())
			img.show()
			self.pixmap_fil = self.dame_pixmap(img)
			self.label_img_fil.setPixmap(self.pixmap_fil)
			self.label_img_fil.repaint()
		#except Exception:
		#	print("Error en algun parametro.")


	def dame_img_PIL(self, path):
		img = QImage(path)
		buffer = QBuffer()
		buffer.open(QBuffer.ReadWrite)
		img.save(buffer, Path(path).suffix[1:])
		return Image.open(io.BytesIO(buffer.data()))

	def dame_pixmap(self, img):
		qim = ImageQt(img)
		pix = QPixmap.fromImage(qim)
		return pix

	def tono_gris1(self, img):
		pixels = img.load() #Creamos el mapa de pixeles.
		for i in range(img.size[0]):    #columnas:
			for j in range(img.size[1]):    #renglones
				#Obtenemos el gris:
				gris = int(rojo(pixels[i,j]) * 0.3 + verde(pixels[i,j]) * 0.59 + azul(pixels[i,j]) * 0.11)
				pixels[i,j] = (gris, gris, gris) #ponemos el nuevo color.
		return img

	def tono_gris2(self, img):
		pixels = img.load() 
		for i in range(img.size[0]):    
			for j in range(img.size[1]):    
				#Obtenemos el gris:
				gris = (rojo(pixels[i,j]) + verde(pixels[i,j]) + azul(pixels[i,j]))//3
				pixels[i,j] = (gris, gris, gris) #ponemos el nuevo color.
		return img
		

	def tono_gris3(self, img):
		pixels = img.load() 
		for i in range(img.size[0]):    
			for j in range(img.size[1]):   
				#Obtenemos el gris:
				maximo = max(rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j]))
				minimo = min(rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j]))
				gris = (maximo + minimo)//2
				pixels[i,j] = (gris, gris, gris) #ponemos el nuevo color.
		return img
		

	def tono_gris4(self, img):
		pixels = img.load() 
		for i in range(img.size[0]):    
			for j in range(img.size[1]):    
				#Obtenemos el gris:
				gris = max(rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j]))
				pixels[i,j] = (gris, gris, gris) #ponemos el nuevo color.
		return img
		

	def tono_gris5(self, img):
		pixels = img.load() 
		for i in range(img.size[0]):    
			for j in range(img.size[1]):    
				#Obtenemos el gris:
				gris = min(rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j]))
				pixels[i,j] = (gris, gris, gris) #ponemos el nuevo color.
		
		return img

	def tono_gris6(self, img):
		pixels = img.load() 
		for i in range(img.size[0]):    
			for j in range(img.size[1]):    
				pixels[i,j] = (rojo(pixels[i,j]), rojo(pixels[i,j]), rojo(pixels[i,j])) #ponemos el nuevo color.
		return img
		

	def tono_gris7(self, img):
		pixels = img.load() 
		for i in range(img.size[0]):    
			for j in range(img.size[1]):    
				pixels[i,j] = (verde(pixels[i,j]), verde(pixels[i,j]), verde(pixels[i,j])) #ponemos el nuevo color.
		return img
		
		
	def tono_gris8(self, img):
		pixels = img.load() 
		for i in range(img.size[0]):   
			for j in range(img.size[1]):    
				pixels[i,j] = (azul(pixels[i,j]), azul(pixels[i,j]), azul(pixels[i,j])) #ponemos el nuevo color.
		return img
		
		
	def brillo(self, img, cte):
		pixels = img.load()
		for i in range(img.size[0]):   
			for j in range(img.size[1]):
				n_r = rojo(pixels[i,j]) + cte  
				n_v = verde(pixels[i,j]) + cte
				n_a = azul(pixels[i,j]) + cte
				pixels[i,j] = (255 if (n_r >= 255) else (0 if (n_r <= 0) else n_r), 
				255 if (n_v > 255) else (0 if (n_v < 0) else n_v), 
				255 if (n_a > 255) else (0 if (n_a < 0) else n_a))
		return img
		
		
	def mosaico(self, img, n, m):
		pixels = img.load() 
		for i in range(img.size[0]):    
			for j in range(img.size[1]):    
				if i % n == 0 and j % m == 0 and i != 0 and j != 0:
					promedio = self.saca_promedio(pixels, i, j, n, m)
					for x in range(i-n, i):
						for y in range(j-m, j):
							pixels[x,y] = (promedio[0], promedio[1], promedio[2]) #ponemos el nuevo color.
		return img
		
		
	def inverso(self, img):
		pixels = img.load() 
		for i in range(img.size[0]):   
			for j in range(img.size[1]):    
				pixels[i,j] = ((rojo(pixels[i,j]) - 255) * (-1), 
					(verde(pixels[i,j]) - 255) * (-1), 
					(azul(pixels[i,j]) - 255) * (-1)) 
		return img
		
	
	def saca_promedio(self, pixels, i, j, n, m):
		sumaR = 0
		sumaV = 0
		sumaA = 0
		for x in range(i-n, i):
			for y in range(j-m, j):
				sumaR += rojo(pixels[x,y])
				sumaV += verde(pixels[x,y]) 
				sumaA += azul(pixels[x,y])
		return [sumaR//(n*m), sumaV//(n*m), sumaA//(n*m)]

	def alto_contraste(self, img):
		img = self.tono_gris1(img)
		pixels = img.load()

		for i in range(img.size[0]):    
			for j in range(img.size[1]):
				if rojo(pixels[i,j]) > 127:
					n_rojo = 255
				else:
					n_rojo = 0
				if verde(pixels[i,j]) > 127:
					n_verde = 255
				else:
					n_verde = 0
				if azul(pixels[i,j]) > 127:
					n_azul = 255
				else:
					n_azul = 0	

				pixels[i,j] = (n_rojo, n_verde, n_azul)

		return img
		

	def blur(self, img):
		pixels = img.load() 
		for i in range(2, img.size[0]):   
			for j in range(2, img.size[1]):
				try:
					n_rojo = (rojo(pixels[i, j-2])
					+ rojo(pixels[i-1, j-1]) + rojo(pixels[i, j-1]) + rojo(pixels[i+1, j-1]) 
					+ rojo(pixels[i-2, j]) + rojo(pixels[i-1, j]) + rojo(pixels[i, j]) + rojo(pixels[i+1, j]) + rojo(pixels[i+2, j]) 
					+ rojo(pixels[i-1, j+1]) + rojo(pixels[i, j+1]) + rojo(pixels[i+1, j+1])
					+ rojo(pixels[i, j+2]))//13
					if n_rojo > 255:
						n_rojo = 255
					if n_rojo < 0:
						n_rojo = 0
					n_verde = (verde(pixels[i, j-2])
					+ verde(pixels[i-1, j-1]) + verde(pixels[i, j-1]) + verde(pixels[i+1, j-1]) 
					+ verde(pixels[i-2, j]) + verde(pixels[i-1, j]) + verde(pixels[i, j]) + verde(pixels[i+1, j]) + verde(pixels[i+2, j]) 
					+ verde(pixels[i-1, j+1]) + verde(pixels[i, j+1]) + verde(pixels[i+1, j+1])
					+ verde(pixels[i, j+2]))//13
					if n_verde > 255:
						n_verde = 255
					if n_verde < 0:
						n_verde = 0
					n_azul = (azul(pixels[i, j-2])
					+ azul(pixels[i-1, j-1]) + azul(pixels[i, j-1]) + azul(pixels[i+1, j-1]) 
					+ azul(pixels[i-2, j]) + azul(pixels[i-1, j]) + azul(pixels[i, j]) + azul(pixels[i+1, j]) + azul(pixels[i+2, j]) 
					+ azul(pixels[i-1, j+1]) + azul(pixels[i, j+1]) + azul(pixels[i+1, j+1])
					+ azul(pixels[i, j+2]))//13
					if n_azul > 255:
						n_azul = 255
					if n_azul < 0:
						n_azul = 0
					pixels[i,j] = (n_rojo, n_verde, n_azul)
				except Exception:
					pixels[i, j] = pixels[i, j]
		return img
		

	def motion_blur(self, img):
		pixels = img.load() 
		for i in range(2, img.size[0]):   
			for j in range(2, img.size[1]):
				try:
					n_rojo = (rojo(pixels[i-2, j-2]) + rojo(pixels[i-1, j-1]) + rojo(pixels[i, j]) 
						+ rojo(pixels[i+1, j+1]) + rojo(pixels[i+2, j+2]))//5
					if n_rojo > 255:
						n_rojo = 255
					if n_rojo < 0:
						n_rojo = 0
					n_verde = (verde(pixels[i-2, j-2]) + verde(pixels[i-1, j-1]) + verde(pixels[i, j]) 
						+ verde(pixels[i+1, j+1]) + verde(pixels[i+2, j+2]))//5
					if n_verde > 255:
						n_verde = 255
					if n_verde < 0:
						n_verde = 0
					n_azul = (azul(pixels[i-2, j-2]) + azul(pixels[i-1, j-1]) + azul(pixels[i, j]) 
						+ azul(pixels[i+1, j+1]) + azul(pixels[i+2, j+2]))//5
					if n_azul > 255:
						n_azul = 255
					if n_azul < 0:
						n_azul = 0
					pixels[i,j] = (n_rojo, n_verde, n_azul)
				except Exception:
					pixels[i, j] = pixels[i, j]
		return img
		

	def edges(self, img):
		pixels = img.load() 
		for i in range(2, img.size[0]):   
			for j in range(2, img.size[1]):
				try:
					n_rojo = ((rojo(pixels[i-2, j-2]) * (-1)) + (rojo(pixels[i-1, j-1]) * (-2)) + (rojo(pixels[i, j]) * (6)) 
						+ (rojo(pixels[i+1, j+1]) * (-2)) + (rojo(pixels[i+2, j+2]) * (-1)))
					if n_rojo > 255:
						n_rojo = 255
					if n_rojo < 0:
						n_rojo = 0
					n_verde = ((verde(pixels[i-2, j-2]) * (-1)) + (verde(pixels[i-1, j-1]) * (-2)) + (verde(pixels[i, j]) * (6)) 
						+ (verde(pixels[i+1, j+1]) * (-2)) + (verde(pixels[i+2, j+2]) * (-1)))
					if n_verde > 255:
						n_verde = 255
					if n_verde < 0:
						n_verde = 0
					n_azul = ((azul(pixels[i-2, j-2]) * (-1)) + (azul(pixels[i-1, j-1]) * (-2)) + (azul(pixels[i, j]) * (6)) 
						+ (azul(pixels[i+1, j+1]) * (-2)) + (azul(pixels[i+2, j+2]) * (-1)))
					if n_azul > 255:
						n_azul = 255
					if n_azul < 0:
						n_azul = 0
					pixels[i,j] = (n_rojo, n_verde, n_azul)
				except Exception:
					pixels[i, j] = pixels[i, j]
		return img
		

	def sharpen(self, img):
		pixels = img.load() 
		for i in range(1, img.size[0]):   
			for j in range(1, img.size[1]):
				try:
					n_rojo = ((rojo(pixels[i-1, j-1]) * (-1)) + (rojo(pixels[i, j-1]) * (-1)) + (rojo(pixels[i+1, j-1]) * (-1))
						+ (rojo(pixels[i-1, j]) * (-1)) + (rojo(pixels[i, j]) * 9) + (rojo(pixels[i+1, j]) * (-1))
						+ (rojo(pixels[i-1, j+1]) * (-1)) + (rojo(pixels[i, j+1]) * (-1)) + (rojo(pixels[i+1, j+1]) * (-1)))
					if n_rojo > 255:
						n_rojo = 255
					if n_rojo < 0:
						n_rojo = 0
					n_verde = ((verde(pixels[i-1, j-1]) * (-1)) + (verde(pixels[i, j-1]) * (-1)) + (verde(pixels[i+1, j-1]) * (-1))
						+ (verde(pixels[i-1, j]) * (-1)) + (verde(pixels[i, j]) * 9) + (verde(pixels[i+1, j]) * (-1))
						+ (verde(pixels[i-1, j+1]) * (-1)) + (verde(pixels[i, j+1]) * (-1)) + (verde(pixels[i+1, j+1]) * (-1)))
					if n_verde > 255:
						n_verde = 255
					if n_verde < 0:
						n_verde = 0
					n_azul = ((azul(pixels[i-1, j-1]) * (-1)) + (azul(pixels[i, j-1]) * (-1)) + (azul(pixels[i+1, j-1]) * (-1))
						+ (azul(pixels[i-1, j]) * (-1)) + (azul(pixels[i, j]) * 9) + (azul(pixels[i+1, j]) * (-1))
						+ (azul(pixels[i-1, j+1]) * (-1)) + (azul(pixels[i, j+1]) * (-1)) + (azul(pixels[i+1, j+1]) * (-1)))
					if n_azul > 255:
						n_azul = 255
					if n_azul < 0:
						n_azul = 0

					pixels[i,j] = (n_rojo, n_verde, n_azul)
				except Exception:
					pixels[i, j] = pixels[i, j]
		return img				

	def emboss(self, img):
		pixels = img.load() 
		for i in range(1, img.size[0]):   
			for j in range(1, img.size[1]):
				try:
					n_rojo = ((rojo(pixels[i-1, j-1]) * (-1)) + (rojo(pixels[i, j-1]) * (-1))
						+ (rojo(pixels[i-1, j]) * (-1)) + rojo(pixels[i+1, j]) + rojo(pixels[i, j+1]) + rojo(pixels[i+1, j+1]))
					if n_rojo > 255:
						n_rojo = 255
					if n_rojo < 0:
						n_rojo = 0
					n_verde = ((verde(pixels[i-1, j-1]) * (-1)) + (verde(pixels[i, j-1]) * (-1))
						+ (verde(pixels[i-1, j]) * (-1)) + verde(pixels[i+1, j]) + verde(pixels[i, j+1]) + verde(pixels[i+1, j+1]))
					if n_verde > 255:
						n_verde = 255
					if n_verde < 0:
						n_verde = 0
					n_azul = ((azul(pixels[i-1, j-1]) * (-1)) + (azul(pixels[i, j-1]) * (-1)) + (azul(pixels[i-1, j]) * (-1)) 
						+ azul(pixels[i+1, j]) + azul(pixels[i, j+1]) + azul(pixels[i+1, j+1]))
					if n_azul > 255:
						n_azul = 255
					if n_azul < 0:
						n_azul = 0

					pixels[i,j] = (n_rojo, n_verde, n_azul)
				except Exception:
					pixels[i, j] = pixels[i, j]
		return img

	def mediana(self, img):
		pixels = img.load() 
		for i in range(1, img.size[0]):   
			for j in range(1, img.size[1]):
				try:
					m = 9//2
					n_rojo = [rojo(pixels[i-1, j-1]), rojo(pixels[i, j-1]), rojo(pixels[i+1, j-1])
						 ,rojo(pixels[i-1, j]),  rojo(pixels[i, j]), rojo(pixels[i+1, j])
						 ,rojo(pixels[i-1, j+1]), rojo(pixels[i, j+1]), rojo(pixels[i+1, j+1])]
					n_rojo.sort()
					n_verde = [verde(pixels[i-1, j-1]), verde(pixels[i, j-1]), verde(pixels[i+1, j-1])
						 ,verde(pixels[i-1, j]),  verde(pixels[i, j]), verde(pixels[i+1, j])
						 ,verde(pixels[i-1, j+1]), verde(pixels[i, j+1]), verde(pixels[i+1, j+1])]
					n_verde.sort()
					n_azul = [azul(pixels[i-1, j-1]), azul(pixels[i, j-1]), azul(pixels[i+1, j-1])
						 ,azul(pixels[i-1, j]),  azul(pixels[i, j]), azul(pixels[i+1, j])
						 ,azul(pixels[i-1, j+1]), azul(pixels[i, j+1]), azul(pixels[i+1, j+1])]
					n_azul.sort()

					pixels[i,j] = (n_rojo[m], n_verde[m], n_azul[m])

				except Exception:
					pixels[i, j] = pixels[i, j]
		return img

	def letra_color(self, img):
		n=8
		m=8
		mosaico = self.mosaico(img, n, m)
		pixels = mosaico.load()
		rejilla = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		draw = ImageDraw.Draw(rejilla)
		font = ImageFont.truetype("fonts/courbd.ttf", 10)
		for i in range(0, mosaico.size[0], 8):
			for j in range(0, mosaico.size[1], 8):
				draw.text((i, j), "X", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
		
		
		return rejilla
		
	def letra_tono_gris(self, img):
		n=8
		m=8
		tono_gris = self.tono_gris1(img)
		mosaico = self.mosaico(tono_gris, n, m)

		pixels = mosaico.load()
		rejilla = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		draw = ImageDraw.Draw(rejilla)
		font = ImageFont.truetype("fonts/courbd.ttf", 10)
		for i in range(0, mosaico.size[0], 8):
			for j in range(0, mosaico.size[1], 8):
				draw.text((i, j), "X", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
		
		
		return rejilla

	def letras_bn(self, img):
		n=8
		m=8
		tgris = self.tono_gris1(img)
		mosaico = self.mosaico(tgris, n, m)

		pixels = mosaico.load()
		rejilla = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		draw = ImageDraw.Draw(rejilla)
		font = ImageFont.truetype("fonts/courbd.ttf", 10)
		for i in range(0, mosaico.size[0], 8):
			for j in range(0, mosaico.size[1], 8):
				prom = ((rojo(pixels[i, j]) + verde(pixels[i, j]) + azul(pixels[i, j]))//3)
				if (prom >= 0 and prom < 16): 
					draw.text((i, j), "M", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 16 and prom < 32): 
					draw.text((i, j), "N", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 32 and prom < 48): 
					draw.text((i, j), "H", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 48 and prom < 64): 
					draw.text((i, j), "#", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 64 and prom < 80): 
					draw.text((i, j), "Q", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 80 and prom < 96): 
					draw.text((i, j), "U", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 96 and prom < 112): 
					draw.text((i, j), "A", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 112 and prom < 128): 
					draw.text((i, j), "D", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 128 and prom < 144): 
					draw.text((i, j), "O", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 144 and prom < 160): 
					draw.text((i, j), "Y", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 160 and prom < 176): 
					draw.text((i, j), "2", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 176 and prom < 192): 
					draw.text((i, j), "$", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 192 and prom < 208): 
					draw.text((i, j), "%", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 208 and prom < 224): 
					draw.text((i, j), "+", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 224 and prom < 240): 
					draw.text((i, j), "_", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 240 and prom < 256): 
					draw.text((i, j), " ", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)

		
		return rejilla

	def letras_c(self, img):
		n=8
		m=8

		mosaico = self.mosaico(img, n, m)

		pixels = mosaico.load()
		rejilla = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		draw = ImageDraw.Draw(rejilla)
		font = ImageFont.truetype("fonts/courbd.ttf", 10)
		for i in range(0, mosaico.size[0], 8):
			for j in range(0, mosaico.size[1], 8):
				prom = ((rojo(pixels[i, j]) + verde(pixels[i, j]) + azul(pixels[i, j]))//3)
				if (prom >= 0 and prom < 16): 
					draw.text((i, j), "M", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 16 and prom < 32): 
					draw.text((i, j), "N", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 32 and prom < 48): 
					draw.text((i, j), "H", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 48 and prom < 64): 
					draw.text((i, j), "#", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 64 and prom < 80): 
					draw.text((i, j), "Q", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 80 and prom < 96): 
					draw.text((i, j), "U", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 96 and prom < 112): 
					draw.text((i, j), "A", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 112 and prom < 128): 
					draw.text((i, j), "D", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 128 and prom < 144): 
					draw.text((i, j), "O", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 144 and prom < 160): 
					draw.text((i, j), "Y", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 160 and prom < 176): 
					draw.text((i, j), "2", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 176 and prom < 192): 
					draw.text((i, j), "$", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 192 and prom < 208): 
					draw.text((i, j), "%", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 208 and prom < 224): 
					draw.text((i, j), "+", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 224 and prom < 240): 
					draw.text((i, j), "_", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 240 and prom < 256): 
					draw.text((i, j), " ", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
		
		
		return rejilla


	def texto_def(self, img, cad):
		try:
			n=8
			m=8
			mosaico = self.mosaico(img.copy(), n, m)
			pixels = mosaico.load()
			rejilla = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
			draw = ImageDraw.Draw(rejilla)
			font = ImageFont.truetype("fonts/courbd.ttf", 10)
			for i in range(0, mosaico.size[0], (len(cad) * 6) ):
				for j in range(0, mosaico.size[1], 8):
					draw.text((i, j), cad, (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
			
			
			return rejilla
		except Exception:
			print("ERROR! Escoja entrada valida.")
			return img

	def naipes(self, img):
		n=8
		m=8

		mosaico = self.mosaico(img, n, m)

		pixels = mosaico.load()
		rejilla = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		draw = ImageDraw.Draw(rejilla)
		font = ImageFont.truetype("fonts/PLAYCRDS.TTF", 13)
		for i in range(0, mosaico.size[0], 10):
			for j in range(0, mosaico.size[1], 10):
				prom = ((rojo(pixels[i, j]) + verde(pixels[i, j]) + azul(pixels[i, j]))//3)
				if (prom >= 0 and prom < 23): 
					draw.text((i, j), "Z", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 23 and prom < 46): 
					draw.text((i, j), "W", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 46 and prom < 69): 
					draw.text((i, j), "V", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 69 and prom < 92): 
					draw.text((i, j), "U", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 92 and prom < 115): 
					draw.text((i, j), "T", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 115 and prom < 138): 
					draw.text((i, j), "S", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 138 and prom < 161): 
					draw.text((i, j), "R", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 161 and prom < 184): 
					draw.text((i, j), "Q", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 184 and prom < 207): 
					draw.text((i, j), "P", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 207 and prom < 230): 
					draw.text((i, j), "O", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 230 and prom < 256): 
					draw.text((i, j), "N", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
		
		
		return rejilla

	def domino(self, img):
		n=8
		m=8

		mosaico = self.mosaico(img, n, m)

		pixels = mosaico.load()
		rejilla = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		draw = ImageDraw.Draw(rejilla)
		font = ImageFont.truetype("fonts/Lasvbld_.ttf", 10)
		for i in range(0, mosaico.size[0], 8):
			for j in range(0, mosaico.size[1], 8):
				prom = ((rojo(pixels[i, j]) + verde(pixels[i, j]) + azul(pixels[i, j]))//3)
				if (prom >= 0 and prom < 37): 
					draw.text((i, j), "6", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 37 and prom < 74): 
					draw.text((i, j), "5", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 74 and prom < 111): 
					draw.text((i, j), "4", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 111 and prom < 148): 
					draw.text((i, j), "3", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 148 and prom < 185): 
					draw.text((i, j), "2", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 185 and prom < 222): 
					draw.text((i, j), "1", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
				elif(prom >= 222 and prom < 256): 
					draw.text((i, j), "0", (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])), font=font)
		
				
		return rejilla

	def quitar_marca(self, img):
		pixels = img.load()
		# Quitamos la marca de agua de las partes en las que choca con lo que no es blanco. 
		for i in range(img.size[0]):    
			for j in range(img.size[1]): 
				if(not es_gris(pixels[i,j])):
					if(rojo(pixels[i,j]) > verde(pixels[i,j]) and rojo(pixels[i,j]) > azul(pixels[i,j])):
						pixels[i,j] = (rojo(pixels[i,j]), rojo(pixels[i,j]), rojo(pixels[i,j]))
					elif(verde(pixels[i,j]) > azul(pixels[i,j])):
						pixels[i,j] = (verde(pixels[i,j]), verde(pixels[i,j]), verde(pixels[i,j]))  
					else:
						pixels[i,j] = (azul(pixels[i,j]), azul(pixels[i,j]), azul(pixels[i,j]))
				else:
					pixels[i,j] = (rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j])) #ponemos el nuevo color.
		mosaico = self.mosaico(img, 1, 2)
		pixels2 = mosaico.load()
		# Hacemos un efecto pequenio de mosaico y obtenemos color promedio intentando quitar la marca de agua.
		for i in range(0, mosaico.size[0]):
			for j in range(0, mosaico.size[1]):
				prom = ((rojo(pixels2[i, j]) + verde(pixels2[i, j]) + azul(pixels2[i, j]))/3)
				if (prom >= 206.5):
					pixels2[i,j] = (255,255,255)
				else:
					pixels2[i,j] = (rojo(pixels2[i,j]), verde(pixels2[i,j]), azul(pixels2[i,j]))

		return mosaico

	def ecualizar_img(self, img):
		gris = self.tono_gris1(img)
		cdf = self.dame_cdf(gris)
		n = gris.size[0]
		m = gris.size[1]
		print(cdf)
		pixels = gris.load()
		nm = n*m
		cdf_min_k = min(cdf.keys(), key=(lambda k: cdf[k]))
		cdf_min = cdf[cdf_min_k]
		nm_cdf_min = nm - cdf_min
		for i in range(n):
			for j in range(m):
				r = rojo(pixels[i,j])
				nuevo_pix = int( ((cdf[str(r)]-cdf_min)/nm_cdf_min) * 255)
				pixels[i,j] = (nuevo_pix, nuevo_pix, nuevo_pix)

		return gris

	def dame_cdf(self, img):
		pixels = img.load()
		cdf = dict()
		val = []
		n = img.size[0]
		m = img.size[1]
		for i in range(n):
			for j in range(m):
				key = str(rojo(pixels[i, j]))
				if cdf == {}:
					c_v = cuenta_val(int(key), pixels, n, m)
					cdf.update([(key, c_v)])
					val += [c_v]
				elif key not in cdf:
					value_prev = val[-1]
					value_this = cuenta_val(int(key), pixels, n, m)
					value_new = value_this + value_prev
					cdf.update([(key, value_new)])
					val += [value_new]
		return cdf

	def semitonosA(self, img, n, m):
		gris = self.tono_gris1(img)
		mosaico = self.mosaico(gris, n, m)
		pixels = mosaico.load()
		
		nueva_img = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		a = []
		size = n, m
		for i in range(1, 11):
			semitono = self.dame_img_PIL("semitonos/a"+ str(i)+ ".jpg")
			semitono.thumbnail(size, Image.ANTIALIAS)
			a.append(semitono)

		for i in range(0, mosaico.size[0],n):
			for j in range(0, mosaico.size[1],m):
				prom = ((rojo(pixels[i, j]) + verde(pixels[i, j]) + azul(pixels[i, j]))//3)
				if (prom >= 0 and prom < 25):
					nueva_img.paste(a[0], (i,j))
				elif (prom >= 25 and prom < 50): 
					nueva_img.paste(a[1], (i,j))
				elif (prom >= 50 and prom < 75): 
					nueva_img.paste(a[2], (i,j))
				elif (prom >= 75 and prom < 100): 
					nueva_img.paste(a[3], (i,j))
				elif (prom >= 100 and prom < 125): 
					nueva_img.paste(a[4], (i,j))
				elif (prom >= 125 and prom < 150): 
					nueva_img.paste(a[5], (i,j))
				elif (prom >= 150 and prom < 175): 
					nueva_img.paste(a[6], (i,j))
				elif (prom >= 175 and prom < 200): 
					nueva_img.paste(a[7], (i,j))
				elif (prom >= 200 and prom < 225): 
					nueva_img.paste(a[8], (i,j))
				elif (prom >= 225 and prom < 255): 
					nueva_img.paste(a[9], (i,j))

		return nueva_img

	def semitonosB(self, img, n, m):
		gris = self.tono_gris1(img)
		mosaico = self.mosaico(gris, n, m)
		pixels = mosaico.load()
		
		nueva_img = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		b = []
		size = n, m
		for i in range(10):
			semitono = self.dame_img_PIL("semitonos/b"+ str(i)+ ".jpg")
			semitono.thumbnail(size, Image.ANTIALIAS)
			b.append(semitono)

		for i in range(0, mosaico.size[0], n):
			for j in range(0, mosaico.size[1], m):
				prom = ((rojo(pixels[i, j]) + verde(pixels[i, j]) + azul(pixels[i, j]))//3)
				if (prom >= 0 and prom < 25):
					nueva_img.paste(b[9], (i,j))
				elif (prom >= 25 and prom < 50): 
					nueva_img.paste(b[8], (i,j))
				elif (prom >= 50 and prom < 75): 
					nueva_img.paste(b[7], (i,j))
				elif (prom >= 75 and prom < 100): 
					nueva_img.paste(b[6], (i,j))
				elif (prom >= 100 and prom < 125): 
					nueva_img.paste(b[5], (i,j))
				elif (prom >= 125 and prom < 150): 
					nueva_img.paste(b[4], (i,j))
				elif (prom >= 150 and prom < 175): 
					nueva_img.paste(b[3], (i,j))
				elif (prom >= 175 and prom < 200): 
					nueva_img.paste(b[2], (i,j))
				elif (prom >= 200 and prom < 225): 
					nueva_img.paste(b[1], (i,j))
				elif (prom >= 225 and prom < 255): 
					nueva_img.paste(b[0], (i,j))

		return nueva_img

	def semitonosC(self, img, n, m):
		gris = self.tono_gris1(img)
		mosaico = self.mosaico(gris, n, m)
		pixels = mosaico.load()
		
		nueva_img = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		c = []
		size = n, m
		for i in range(5):
			semitono = self.dame_img_PIL("semitonos/b"+ str(i)+ ".jpg")
			semitono.thumbnail(size, Image.ANTIALIAS)
			c.append(semitono)

		for i in range(0, mosaico.size[0],n):
			for j in range(0, mosaico.size[1],m):
				prom = ((rojo(pixels[i, j]) + verde(pixels[i, j]) + azul(pixels[i, j]))//3)
				if (prom >= 0 and prom < 50):
					nueva_img.paste(c[4], (i,j))
				elif (prom >= 50 and prom < 100):
					nueva_img.paste(c[3], (i,j))
				elif (prom >= 100 and prom < 150):
					nueva_img.paste(c[2], (i,j))
				elif (prom >= 150 and prom < 200): 
					nueva_img.paste(c[1], (i,j))
				elif (prom >= 200 and prom < 255): 
					nueva_img.paste(c[0], (i,j))

		return nueva_img

	def luz_negra(self, img, peso):
		pixels = img.load()
		for i in range(img.size[0]):
			for j in range(img.size[1]):
				l = int(rojo(pixels[i,j]) * 0.3 + verde(pixels[i,j]) * 0.59 + azul(pixels[i,j]) * 0.11)
				nuevo_r = abs(rojo(pixels[i,j]) - l) * peso
				nuevo_v = abs(verde(pixels[i,j]) - l) * peso
				nuevo_a = abs(azul(pixels[i,j]) - l) * peso
				if nuevo_r > 256:
					nuevo_r = 255
				if nuevo_v > 256:
					nuevo_v = 255
				if nuevo_a > 256:
					nuevo_a = 255
				pixels[i,j] = (nuevo_r, nuevo_v, nuevo_a)

		return img

	def at_t(self, img):
		gris = self.tono_gris1(img)
		alto_c = self.alto_contraste(gris)
		n_s = alto_c.size[0]//18
		puntos = []
		pixels = alto_c.load()
		for i in range(alto_c.size[0]):
			for j in range(0, alto_c.size[1]-n_s, n_s):
				black = 0
				for k in range(j, j+n_s):
					if(int(rojo(pixels[i,k]) * 255) == 0):
						black+=1

				puntos = [False for i in range(n_s)]
				n = black//2

				if(black % 2 == 0):
					m = n-1
				else:
					m = n

				for l in range((n_s//2)-n, (n_s//2)+m):
					puntos[l] = True

				for k in range(j, j+n_s):
					if(puntos[k-j]):
						pixels[i, k] = (0, 0, 0)
					else:
						pixels[i, k] = (255, 255, 255)

			pixels[i, j] = (0, 0, 0)

		return alto_c

	def recursiva_c(self, img, n, m):
		img_t = self.mosaico(img, n, m)
		nueva_img = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		size = n, m

		pixels = img_t.load()
		for i in range(0, img_t.size[0], n):
			for j in range(0, img_t.size[1], m):
				c_web = color_websafe_cercano(rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j]))
				nueva_img.paste(c_web, (i-n,j-m, i, j))
				
		return nueva_img

	def recursiva_b(self, img, n, m):
		img_gris = self.tono_gris1(img)
		img_t = self.mosaico(img, n, m)
		nueva_img = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		size = n, m
		t_g = []

		for i in range(20):
			img_b = self.brillo(img_gris.copy(), 127-(i*20))
			img_b.thumbnail(size, Image.ANTIALIAS)
			t_g.append(img_b)

		pixels = img_t.load()
		for i in range(0, img_t.size[0], n):
			for j in range(0, img_t.size[1], m):
				prom = ((rojo(pixels[i, j]) + verde(pixels[i, j]) + azul(pixels[i, j]))//3)
				if (prom >= 0 and prom < 20):
					nueva_img.paste(t_g[19], (i,j))
				elif (prom >= 20 and prom < 30):
					nueva_img.paste(t_g[18], (i,j))
				elif (prom >= 30 and prom < 40):
					nueva_img.paste(t_g[17], (i,j))
				elif (prom >= 40 and prom < 50):
					nueva_img.paste(t_g[16], (i,j))
				elif (prom >= 50 and prom < 60):
					nueva_img.paste(t_g[15], (i,j))
				elif (prom >= 60 and prom < 70):
					nueva_img.paste(t_g[14], (i,j))
				elif (prom >= 70 and prom < 80):
					nueva_img.paste(t_g[13], (i,j))
				elif (prom >= 80 and prom < 90):
					nueva_img.paste(t_g[12], (i,j))
				elif (prom >= 90 and prom < 100): 
					nueva_img.paste(t_g[11], (i,j))
				elif (prom >= 100 and prom < 110): 
					nueva_img.paste(t_g[10], (i,j))
				elif (prom >= 110 and prom < 120): 
					nueva_img.paste(t_g[9], (i,j))
				elif (prom >= 120 and prom < 140): 
					nueva_img.paste(t_g[8], (i,j))
				elif (prom >= 140 and prom < 150): 
					nueva_img.paste(t_g[7], (i,j))
				elif (prom >= 150 and prom < 160): 
					nueva_img.paste(t_g[6], (i,j))
				elif (prom >= 160 and prom < 170): 
					nueva_img.paste(t_g[5], (i,j))
				elif (prom >= 170 and prom < 180): 
					nueva_img.paste(t_g[4], (i,j))
				elif (prom >= 180 and prom < 200): 
					nueva_img.paste(t_g[3], (i,j))
				elif (prom >= 200 and prom < 210): 
					nueva_img.paste(t_g[2], (i,j))
				elif (prom >= 210 and prom < 220): 
					nueva_img.paste(t_g[1], (i,j))
				elif (prom >= 220 and prom < 255): 
					nueva_img.paste(t_g[0], (i,j))
				
		return nueva_img	

	def rubik(self, img, n_colors):
		nueva_img = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		pixels = img.load()

		if n_colors == "256 colores":
			for i in range(img.size[0]):
				for j in range(img.size[1]):
					c_web = color_websafe_cercano(rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j]))
					nueva_img.paste(c_web, (i-1,j-1,i,j))
		else:
			for i in range(img.size[0]):
				for j in range(img.size[1]):
					c_rub = self.color_rubik(rojo(pixels[i,j]), verde(pixels[i,j]), azul(pixels[i,j]))
					nueva_img.paste(c_rub, (i-1,j-1, i, j))
				
		return nueva_img


	def color_rubik(self, r, g, b):
		dist = []
		for color_r in self.colores_r:
			d = math.sqrt((r-color_r[0])**2 + (g-color_r[1])**2 + (b-color_r[2])**2)
			dist.append(d)
		closest = min(dist)
		ind = dist.index(closest)
		return self.colores_r[ind]


	def r_dithering(self, img):
		pixels = img.load()
		for i in range(img.size[0]):
			for j in range(img.size[1]):
				v = rojo(pixels[i,j])
				r = random.randint(0, 255)
				if r > v:
					pixels[i,j] = (0, 0, 0)
				else:
					pixels[i,j] = (255, 255, 255)
		return img

	def fotomosaico(self, img):
		n = 9
		m = 9
		mosaico = self.mosaico(img, n, m)
		if(self.imgs_paquete == [] and self.colores_paquete == []):
			self.carga_imgs_fotomosaico(n, m)

		nueva_img = Image.new("RGB", (img.size[0], img.size[1]), (255,255,255))
		size = n, m

		pixels = mosaico.load()
		for i in range(0, img.size[0], n):
			for j in range(0, img.size[1], m):
				index = self.min_dist_euclidiana(pixels[i, j])
				nueva_img.paste(self.imgs_paquete[index], (i,j))

		return nueva_img

	def carga_imgs_fotomosaico(self, n, m):
		if(self.path_fotomosaico):
			f = open(self.path_fotomosaico[0], "r")
			size = n, m
			for line in f:
				tokens = line.split("/") # En el archivo de texto los valores RGB y el directorio estan
										 # separados por un /, con split nos deja los tokens que queremos.
				self.colores_paquete.append((int(tokens[0]), int(tokens[1]), int(tokens[2])))
				url = une_tokens(tokens[3:]) # Como el url tmb esta separado por / los separa con split, aca hacemos 
											# que la url sea correcta.
				img_mos = Image.open(url)
				img_mos.thumbnail(size, Image.ANTIALIAS)
				self.imgs_paquete.append(img_mos)

			f.close()
		else:
			print("SELECCIONE PRIMERO UN TEXTO CON LA INFO DEL PAQUETE DE IMGS")


	def min_dist_euclidiana(self, pix):
		dist = []
		r = pix[0]
		g = pix[1]
		b = pix[2]
		for color in self.colores_paquete:
			d = math.sqrt((r-color[0])**2 + (g-color[1])**2 + (b-color[2])**2)
			dist.append(d)
		closest = min(dist)
		ind = dist.index(closest)
		return ind