universidad central del ecuador facultad de ingeniería

Anuncio
UNIVERSIDAD CENTRAL DEL ECUADOR
FACULTAD DE INGENIERÍA CIENCIAS FÍSICAS Y MATEMÁTICA
CARRERA DE INGENIERÍA EN COMPUTACIÓN GRÁFICA
DESARROLLO DE UNA APLICACIÓN WEB PARA LA
COMPRESIÓN DE IMÁGENES
TRABAJO DE GRADUACIÓN PREVIO A LA OBTENCIÓN DEL TÍTULO DE
INGENIERO EN COMPUTACIÓN GRÁFICA
AUTOR: VERÓNICA ELIZABETH VICENTE CUEVA
TUTOR: FIS. GONZALO BAYARDO CAMPUZANO NIETO
QUITO – 15 JULIO
2016
DEDICATORIA
El presente proyecto está dedicado a mis padres:
Pedro y Amanda pilares fundamentales en mi vida.
Sin ellos, jamás hubiese podido conseguir lo que
hasta
ahora.
Su
esfuerzo,
humildad
y
perseverancia han sido fuente de inspiración para
superar las adversidades y salir adelante. Sus
consejos y disciplina fueron la motivación principal
para hacer realidad este sueño.
Verónica Vicente
ii
AGRADECIMIENTO
A Dios, por haberme dado la oportunidad de
culminar esta etapa de mi vida.
A mis padres, por todo el esfuerzo, apoyo y amor
incondicional durante esta trayectoria.
A mis hermanos, por estar siempre presentes
acompañándome en todo momento.
A mis profesores, por su tiempo, dedicación y
conocimientos brindados a lo largo de toda mi
carrera profesional.
A mis compañeros, con quiénes año tras año he
compartido conocimientos, tristezas y alegrías.
Verónica Vicente
iii
AUTORIZACIÓN DE LA AUTORÍA INTELECTUAL
Yo, VERÓNICA ELIZABETH VICENTE CUEVA, en calidad de autora del Trabajo
Proyecto Integrador realizado sobre: “DESARROLLO DE UNA APLICACIÓN
WEB PARA LA COMPRESIÓN DE IMÁGENES”, por la presente autorizo a la
UNIVERSIDAD CENTRAL DEL ECUADOR, hacer uso de todos los contenidos
que me pertenecen o parte de los que contiene esta obra, con fines
estrictamente académicos o de investigación.
Los derechos que como autor me corresponden, con excepción de la presente
autorización, seguirán vigentes a mi favor, de conformidad con lo establecido en
los artículos 5, 6, 8, 19 y demás pertinentes de la Ley de Propiedad Intelectual y
su Reglamento.
Asimismo, autorizo a la UNIVERSIDAD CENTRAL DEL ECUADOR para que
realice la digitalización y publicación de este trabajo de investigación en el
repositorio virtual, de conformidad a lo dispuesto en el Art. 144 de la Ley
Orgánica de Educación Superior.
Quito, 15 de Julio de 2016.
Verónica Elizabeth Vicente Cueva
CI: 1718870965
Telf: 0992569910
mail: [email protected]
iv
CERTIFICACIÓN DEL TUTOR
Yo, Gonzalo Bayardo Campuzano Nieto,
titulación
DESARROLLO
DE
UNA
en calidad de tutor del trabajo de
APLICACIÓN
WEB
PARA
LA
COMPRESIÓN DE IMÁGENES, elaborado por la estudiante VERÓNICA
ELIZABETH VICENTE CUEVA de la Carrera de Computación Gráfica, Facultad
de Ingeniería Ciencias Físicas y Matemática de la Universidad Central del
Ecuador, considero que el mismo reúne los requisitos y méritos necesarios en el
campo metodológico y en el campo epistemológico, para ser sometido a la
evaluación por parte del jurado examinador que se designe, por lo que lo
APRUEBO, a fin de que trabajo investigativo sea habilitado para continuar con el
proceso de titulación determinado por la Universidad Central del Ecuador.
En la ciudad de Quito, a los 20 días del mes de Junio de 2016.
Fis. Gonzalo Bayardo Campuzano Nieto
CC. 1708459118
mail: [email protected]
v
vi
vii
CONTENIDO
pág.
DEDICATORIA .................................................................................................... ii
AGRADECIMIENTO ............................................................................................iii
AUTORIZACIÓN DE LA AUTORÍA INTELECTUAL ............................................ iv
CERTIFICACIÓN DEL TUTOR ............................................................................ v
CONTENIDO ..................................................................................................... viii
LISTA DE TABLAS .............................................................................................. x
LISTA DE FIGURAS ........................................................................................... xi
RESUMEN......................................................................................................... xiii
ABSTRACT .......................................................................................................xiv
INTRODUCCIÓN ................................................................................................. 1
1.
DEFINICIÓN DEL PROBLEMA .................................................................... 2
1.1 Antecedentes ............................................................................................. 2
1.2 Planteamiento del problema ....................................................................... 4
1.3 Formulación del problema .......................................................................... 5
1.4 Objetivos .................................................................................................... 5
1.4.1 Objetivo general................................................................................... 5
1.4.2 Objetivos específicos ........................................................................... 5
1.5 Justificación................................................................................................ 5
2.
MARCO TEÓRICO ....................................................................................... 7
2.1 Compresión de imágenes........................................................................... 7
2.1.1 Compresión sin pérdida ...................................................................... 7
a)
Compresión RLE ................................................................................ 7
b)
Compresión LZW ............................................................................... 9
2.1.2 Compresión con pérdida ..................................................................... 9
2.2
a)
Compresión Fractal .......................................................................... 10
b)
Compresión por Wavelets ................................................................ 10
c)
Compresión JPEG ........................................................................... 11
Descompresión.................................................................................... 24
viii
3.
METODOLOGÍA ......................................................................................... 27
3.1 Análisis de los requisitos del software ...................................................... 27
3.1.1 Librería de compresión ...................................................................... 29
3.1.2 Aplicación web ................................................................................... 31
3.2 Diseño ...................................................................................................... 35
3.2.1 Diagrama de clases para la Librería desarrollada .............................. 35
3.2.2 Diagrama para la Aplicación Web ...................................................... 37
3.3 Generación de código ............................................................................. 39
3.3.1 Librería de compresión de imágenes ................................................. 39
3.3.2 Aplicación Web .................................................................................. 40
4.
PRUEBAS Y RESULTADOS ...................................................................... 42
5.
CONCLUSIONES ....................................................................................... 57
6.
RECOMENDACIONES ............................................................................... 59
BIBLIOGRAFÍA .................................................................................................. 60
ANEXOS ........................................................................................................... 64
ix
LISTA DE TABLAS
Tabla 2.1 Matrices de Cuantización: a) Luminancia, b) Crominancia ................. 18
Tabla 2.2 Categorías y bits adicionales para los coeficientes AC ..................... 20
Tabla 2.3 Contenido parcial para la Codificación de Huffman. ........................... 21
Tabla 2.4 Ejemplo Codificación de Huffman para coeficientes AC ..................... 22
Tabla 2.5 Categorías y bits adicionales para los coeficientes DC ...................... 23
Tabla 2.6 Codificación de Huffman de coeficientes DC ..................................... 23
Tabla 2.7 Ejemplo de Codificación de coeficientes DC ...................................... 24
Tabla 4.1 Resultado de compresión de imágenes TIF ....................................... 46
Tabla 4.2 Resultado de compresión de imágenes PNG ..................................... 46
Tabla 4.3 Resultado de compresión de imágenes JPG...................................... 47
Tabla 4.4 Resultado de compresión de imágenes binarias GIF ......................... 48
Tabla 4.5 Resultado de compresión de imágenes a escala de gris TIF ............. 48
Tabla 4.6 Medidas de calidad de cada formato de imagen ................................ 49
Tabla 4.7 Compresión de imágenes utilizando diferentes herramientas ............ 55
x
LISTA DE FIGURAS
Figura 2.1 Método de compresión RLE................................................................ 8
Figura 2.2 Tipos de recorrido de una matriz a) Recorrido por filas b) Recorrido
por columnas ....................................................................................................... 8
Figura 2.3 Esquema de descomposición una imagen por Wavelets. ................ 10
Figura 2.4 a) Imagen Original, b) Descomposición de la imagen en wavelets. ... 11
Figura 2.5 Etapas del proceso de compresión JPEG ......................................... 11
Figura 2.6 Componentes de una imagen a color................................................ 12
Figura 2.7 Descomposición de planos del espacio de color YCBCR.................. 13
Figura 2.8 División de la imagen en bloques de 8x8 píxeles .............................. 15
Figura 2.9 Completar filas y columnas de una imagen ....................................... 15
Figura 2.10 Representación de las frecuencias de una imagen (SlideShare,
2016) ................................................................................................................. 16
Figura 2.11 Compactación de la energía DCT (Wikipedia, 2016) ....................... 17
Figura 2.12 Recorrido de un bloque en zigzag ................................................... 19
Figura 2.13 Vector con pares, luego de aplicar RLE .......................................... 19
Figura 2.14 Codificación DPCM en bloques de imagen. (Martín M. , 2004) ....... 22
Figura 2.15 Código de Huffman de un bloque de imagen. ................................. 24
Figura 3.1 Diagrama de flujo de la aplicación. ................................................... 35
Figura 3.2 Diagrama de clases Librería de compresión de imágenes, método
JPEG. ................................................................................................................ 36
Figura 3.3 Relación entre las clases: Imagen y CompresionJPEG .................... 36
Figura 3.4 Diagrama de clases: Bloque y MatrizBloque ..................................... 37
Figura 3.5 Esquema de aplicación web ............................................................. 37
Figura 3.6 Diagrama de clases de la Aplicación Web ........................................ 38
Figura 4.1 Prueba de imágenes formato TIFF ................................................... 45
Figura 4.2 Prueba de imágenes formato PNG ................................................... 46
Figura 4.3 Resultado de compresión de imágenes JPG .................................... 47
Figura 4.4 Prueba de imágenes binarias formato GIF ........................................ 47
Figura 4.5 Prueba de imágenes escala de grises formato TIFF ......................... 48
Figura 4.6 Gráfico comparativo del ratio de compresión. ................................... 49
Figura 4.7 Porcentaje de compresión ................................................................ 50
Figura 4.8 Error Medio Cuadrático ..................................................................... 50
Figura 4.9 Relación señal ruido ......................................................................... 51
Figura 4.10 Medida de calidad estructural ......................................................... 51
Figura 4.11 Compresión de una imagen de formato bmp .................................. 53
xi
Figura 4.12 Compresión de una imagen de formato tif ...................................... 53
Figura 4.13 Compresión de una imagen de formato gif...................................... 54
Figura 4.14 Compresión de una imagen de formato png ................................... 54
Figura 4.15 Compresión de una imagen de formato jpg..................................... 55
Figura 4.16 Comparativo de compresión de imágenes ...................................... 55
xii
RESUMEN
DESARROLLO DE UNA APLICACIÓN WEB PARA LA
COMPRESIÓN DE IMÁGENES
Autor: Verónica Elizabeth Vicente Cueva
Tutor: Fis. Gonzalo Bayardo Campuzano Nieto
En el presente proyecto se realizó un estudio de técnicas de compresión de
imágenes, el cual sirvió de base para el desarrollo de una librería en C#,
apoyada en el método de compresión JPEG; mismo que utiliza algoritmos
matemáticos como por ejemplo la Transformada de coseno y la Cuantización
que permiten eliminar parte de la información de una imagen considerada
imperceptible para el ojo humano. Asimismo se creó una interfaz de usuario
tomando en cuenta la metodología para el desarrollo de aplicaciones web, que
conjuntamente con la librería desarrollada, realizan el proceso de compresión y
descompresión de imágenes. Es decir que esta herramienta permite a los
usuarios reducir el tamaño del archivo de imágenes, sin que afecte la calidad de
las mismas. Además, estas imágenes estarán en formato JPG, se podrán
descargar y visualizar desde cualquier visor de imágenes.
PALABRAS CLAVE: /APLICACIÓN WEB /COMPRESIÓN DE IMÁGENES /
ALGORITMO JPEG /TRANSFORMADA DE COSENO /CUANTIZACIÓN /
DESCOMPRESIÓN DE IMÁGENES/
xiii
ABSTRACT
DEVELOPMENT OF A WEB APPLICATION FOR IMAGES COMPRESSION
Author: Verónica Elizabeth Vicente Cueva
Tutor: Fis. Gonzalo Bayardo Campuzano Nieto
In the current project, a study of images compression technics was conducted,
used as base to develop a library in C#, supported on JPEG compression
method, which uses mathematical algorithms, such as cosine Transform and
Quantization that allows eliminating a part of the information of an imaged,
deemed imperceptible for the naked eye. Likewise, a user interphase was
created taking into account methodology for the development of a web
applications, which jointly with developed library, conduct compression and
decompression process of images. Hence, such a tool allows users reducing the
size of images file, without affecting their quality. Additionally, such images shall
be in JPG format, can be downloaded and viewed from any images viewer.
KEYWORDS:
ALGORITHM
/WEB
APPLICATION
/COSINE
/IMAGES
TRANSFORM
COMPRESSION
/QUANTIZATION
/JPEG
/IMAGES
DECOMPRESSION
I CERTIFY that the above and foregoing is a true and correct translation of the
original document in Spanish.
____________
Ernesto Andino
Certified Translator
IC: 1703852317
xiv
INTRODUCCIÓN
En la actualidad, la imagen digital juega un papel importante en la transmisión de
información, el fácil acceso a los diferentes dispositivos móviles y la rapidez con
que se puede tomar fotografías y capturar cada momento vivido hace que subir
fotos en línea sea cada vez más habitual. Sin embargo existe cierta limitación en
el ancho de banda de los medios de comunicación, así como en el espacio de
almacenamiento.
Existen múltiples programas que permiten realizar un tratamiento previo a las
imágenes con el objetivo de disminuir el peso de las mismas. Algunos de estos
programas necesitan ser instalados ocupando mucho espacio en el disco duro
del ordenador, incluso en algunos casos (como el de Photoshop1) además de
que el programa ocupa espacio en el disco se debe pagar por la licencia. Estos
programas utilizan técnicas de compresión que se pueden clasificar en dos tipos:
sin pérdidas y con pérdidas. La diferencia principal radica en que la compresión
sin pérdida se puede recuperar los datos en forma exacta, mientras que la
compresión con pérdida se recupera una aproximación de los datos.
Por este motivo surge la necesidad de realizar una aplicación web gratuita que
permita a los usuarios reducir el tamaño del archivo de una imagen, mediante el
desarrollo de una Librería basada en la técnica de compresión JPEG; la cual
emplea algoritmos matemáticos para eliminar parte de la información de una
imagen que se considera imperceptible al sistema visual humano.
1
Photoshop, software comercializado por Adobe, utilizado para crear, editar y retocar
imágenes.
1
1. DEFINICIÓN DEL PROBLEMA
1.1 Antecedentes
En los últimos años, la obtención de imágenes digitales es cada vez más
frecuente debido a la facilidad con que se puede digitalizar la información
mediante las herramientas que vienen incorporadas en los dispositivos móviles,
de igual forma compartir imágenes en las diferentes redes sociales, blogs, sitios
web o para uso personal. No obstante, es indispensable comprimir las imágenes
con el fin disminuir el peso para su almacenamiento o posterior transmisión
mejorando así la velocidad de carga de los sitios web, redes sociales, etc.
Actualmente existen programas de compresión de imágenes para PC y
programas de compresión en línea que permiten cargar imágenes desde el
ordenador o importarlas desde otros de sitios web para luego procesarlas y
generar una nueva imagen con menor peso.
Tras realizar una revisión de proyectos relacionados con la compresión de
imágenes podemos nombrar algunos de ellos que están relacionados con el
presente proyecto:

Carlos Giler (2003), en su trabajo de grado titulado “Implementación del
Algoritmo RLC (Run Length Code) para compresión y descompresión
aplicado a datos provenientes de imágenes telemétricas”, orientado en el
área de Electrónica y Telecomunicaciones. Propone un sistema de
monitoreo visual de volcanes para el Departamento de Geofísica de la
Escuela Politécnica Nacional. El sistema se desarrolló en Visual Basic,
está compuesto por una PC con una cámara que permite capturar las
imágenes (formato BMP) en determinado tiempo para luego ser
transmitidas al receptor (otra PC) mediante equipo especializado. La
finalidad de este sistema es acortar el tiempo de transmisión de éstas
imágenes, para lo cual implementa el algoritmo de compresión RLE que
reduce la longitud de cadena de datos de una imagen para ser
transmitida en un menor tiempo.

El trabajo de Mario Sandoval (2008), se denomina “Algoritmo de
compresión de imágenes de alta resolución sin pérdidas”, se trata de un
proyecto desarrollado en C#, implementa el algoritmo de compresión
2
llamado RSM (Recorridos sobre la imagen). Este método lee una
imagen, y obtiene las siguientes características: dimensiones de la
imagen, el número de colores de la imagen, número de píxeles, número
de bits por píxel. Estos datos son guardados en un vector llamado
CADENA y posteriormente este vector se almacena en archivos con
extensión .DAT en formato binario. El autor señala que esta técnica no
presenta pérdida de información.

Manuel Velásquez (2014), realizó el proyecto “Aplicación gráfica para la
compresión de información multimedia”. Es una aplicación de escritorio
desarrollada en Java, permite realizar tres técnicas de compresión: RLE,
LZW y Huffman, estas técnicas son descritas con mayor detalle en el
Capítulo 2.
A continuación se presentan algunos proyectos de código abierto de
compresores de imágenesg.

jep compresor2: Es un pequeño proyecto desarrollado en C++, utiliza
un solo archivo de código jpeg.cpp. Está basado en la compresión JPEG
y además realiza la codificación de Huffman en una sola pasada.

Huffman Swing: Es un proyecto educativo desarrollado en java que
permite realizar la compresión de archivos basado en el método
compresión de Huffman.

Project One - Image Compression3: Es un proyecto desarrollado en
Matlab utiliza la transformada de wavelet para la compresión de
imágenes.
De igual forma, la siguiente lista muestra algunos de los optimizadores de
imágenes en línea más destacados de los cuales se tiene una breve descripción
de sus funcionalidades y tecnologías utilizadas.

Compressor.io4: Es una aplicación web que dispone de dos alternativas
de compresión: la compresión sin pérdida de calidad, que sólo es
aplicable a los formatos JPG y PNG, y compresión con pérdida. Permite
subir solo una imagen a la vez desde una PC y en pocos segundos se
obtiene los resultados, mostrando una vista previa de la imagen original
conjuntamente con la imagen comprimida, donde la diferencia entre las
dos imágenes es imperceptible a la vista. La nueva imagen se puede
descargar directamente a un lugar de almacenamiento de la PC. Las
2
(Google Code , 2016)
(Owlnet.rice.edu, 2014)
4 (Quiñónez, 2014)
3
3
tecnologías que
utiliza son software libre y de código abierto como:
pngquant5, OptiPNG6, JpegOptim7, Gifsicle8 and Scour9.

Kraken.io10: Esta aplicación puede subir 20 imágenes en formato JPG y
PNG simultáneamente con un tamaño máximo de 1 MB por imagen.
También se pueden comprimir imágenes solo copiando la URL de las
mismas. Esta aplicación web se basa en el tipo de compresión con
pérdida, para ello elige la mejor calidad de la imagen en relación a su
tamaño.

TinyPNG11: Utiliza técnicas de compresión con pérdida para reducir el
tamaño de los archivos PNG. Disminuye selectivamente el número de
colores de la imagen, de esta forma se requieren menos bytes para
almacenar los datos de la imagen. Además permite subir 20 archivos de
una vez con un límite de tamaño de 3MB por archivo.
1.2 Planteamiento del problema
Hoy en día nos encontramos con la llamada sociedad de la información donde
las imágenes se han convertido en uno de los elementos importantes en la
comunicación y por ende la mayoría de los mensajes que nos transmiten ya sea
en, televisión, sitios web, redes sociales, etc. utilizan fundamentalmente la
imagen.
Una de las tareas más usuales es el envío de imágenes o fotografías por medio
de las redes sociales ya sea para compartir con amigos, para utilizarlas en el
perfil de alguna red social on-line así como para personalizar una página web.
En la mayoría de los casos esta tarea se complica debido a que las fotos poseen
un tamaño excesivo dificultando así el subirlas a la red.
Existen varios programas dedicados a disminuir el peso de imágenes con el
inconveniente que en algunos casos es necesario instalarlos en la PC ocupando
demasiado espacio en el disco duro o en otros casos como ocurre en algunos
sitios web se debe crear una cuenta para obtener mejores resultados en la
compresión de imágenes.
5
(Pngquant.org)
(Optipng.sourceforge.net)
7 (GitHub)
8 (Kornel.ski)
9 (Codedread.com)
10 (Martín J. , 2013)
11 (Quiñónez, 2014)
6
4
Es por esta razón que surge la necesidad de realizar una aplicación web gratuita
que permita al usuario subir una imagen, y mediante el uso de una Librería de
compresión de imágenes reducir el peso de las mismas.
1.3 Formulación del problema
¿Es posible mejorar la transmisión de una imagen implementando un algoritmo
de compresión en la web que permita disminuir su peso?
1.4 Objetivos
1.4.1 Objetivo general
Diseñar e implementar una aplicación web de compresión de imágenes para
reducir el peso de las mismas.
1.4.2 Objetivos específicos

Analizar el funcionamiento de los algoritmos de compresión más
importantes.

Implementar un algoritmo en la web que permita reducir el peso de
imágenes.

Diseñar una interfaz de usuario que realice el proceso de compresión de
imágenes.
1.5 Justificación
En la actualidad, los sitios web y las redes sociales se están volviendo más
visuales cada día. Las imágenes estimulan la participación de los usuarios, ya
sea porque las comparten, las comentan o lo que es más importante, las
recuerdan. En efecto, el uso de imágenes es fundamental.
Con el fin de ofrecer un mejor rendimiento en la transmisión y almacenamiento
de imágenes en diferentes sitios web o redes sociales, es necesario emplear
técnicas de compresión de imágenes cuyo propósito es eliminar la redundancia
visual. En otras palabras, la compresión de imágenes trata de disminuir el
número de bits necesarios para representar una imagen y hacer que la
transmisión sea más rápida.
Este proyecto plantea el DESARROLLO DE UNA APLICACIÓN WEB PARA LA
COMPRESIÓN DE IMÁGENES, que permita a los usuarios subir sus imágenes e
internamente mediante técnicas de compresión se reduce el peso de las mismas
5
para posteriormente retornar una nueva imagen que a la percepción del ojo
humano es igual que la imagen original pero con la diferencia que presenta un
menor tamaño en el archivo. Es decir que las características de esta imagen
serán lo más parecido posible a las de la imagen original. Adicionalmente el
presente proyecto es de código abierto, el mismo que puede ser utilizado como
una herramienta de
consulta para los estudiantes de la carrera de
COMPUTACIÓN GRÁFICA.
6
2. MARCO TEÓRICO
2.1 Compresión de imágenes12
La compresión de imágenes es un proceso que consiste en reducir la cantidad
de datos necesarios para representar una imagen. Este proceso se realiza
empleando algoritmos matemáticos que disminuyen el peso del archivo con la
finalidad de que ocupe menos espacio en su almacenamiento y de igual manera
se abrevia el tiempo para su posterior transmisión.
Existen dos tipos de compresión de imágenes:

Compresión sin pérdida

Compresión con pérdida
2.1.1 Compresión sin pérdida
Es una técnica que trata de agrupar los datos de una imagen que sean de igual
valor o que tengan alguna característica en común de tal manera que se ocupa
un menor espacio para su representación y se puedan recuperar de manera
intacta los datos originales de la imagen sin que haya pérdida de información.
Algunas de las técnicas que pertenecen a este grupo son:

RLE (Run Length Encoding)

LZW (Lempel Zib Welch)
A continuación se describe cada una de las técnicas antes mencionadas:
a) Compresión RLE13: Es uno de los métodos más antiguos y simples para
compresión de datos, es muy útil en imágenes que contengan grandes áreas
del mismo color. Este método disminuye el tamaño de una cadena de datos
que se repite.
Este algoritmo es de bastante utilidad en imágenes binarias o imágenes
satelitales que poseen varias regiones con pocas gamas de color bien
definidas.
En la figura 2.1 se visualiza
un ejemplo de la forma en que trabaja el
algoritmo RLE sobre una imagen.
12
13
(Sánchez Menéndez, 2012)
(Zanuy, 2000)
7
Recorrido por filas
0
1
2
3
4
5
6
7
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
2
0
0
0
1
0
0
0
0
3
0
0
1
1
1
1
0
0
4
0
1
1
1
1
1
1
0
5
0
1
1
1
1
1
1
0
Contador
6
0
1
1
1
1
1
0
0
7
0
0
0
0
0
0
0
0
( 8, 0)
(4,0) (3,1) (1,0)
(3,0) (4,1) (1,0)
(2,0) (5,1) (1,0)
(3,0) (4,1) (1,0)
(3,0) (4,1) (1,0)
(4,0) (2,1) (2,0)
(8, 0)
Elemento
repetido
Figura 2.1 Método de compresión RLE
Para la implementación de la compresión RLE se debe seguir los siguientes
pasos:
1) Recorrer la imagen píxel a píxel, para esto existen tres formas de
recorrer una imagen: horizontal (por columnas), vertical (por filas) y
en zigzag, como se visualiza en la figura 2.3. En el presente proyecto
se utilizó el recorrido por columnas, es decir el recorrido horizontal.
Figura 2.2 Tipos de recorrido de una matriz a) Recorrido por filas b) Recorrido por columnas
d) Recorrido en zigzag (FileFormat.Info, 2015)
8
2) Emplear una estructura de datos (lista o arreglo) que permita
almacenar los datos de la imagen. Esta estructura está conformada
por dos componentes:

La primera componente se utiliza para contar el número de
veces que se repite dicho elemento.

La segunda componente almacena el elemento que se repite
de manera consecutiva
Estos pasos se realizan en toda la imagen, recorriendo cada uno de los píxeles.
Este método también es utilizado como parte del proceso de otros métodos de
compresión como es el caso de la compresión JPEG, que se describe
posteriormente en el apartado de la compresión con pérdida.
b) Compresión LZW: Es un método de compresión sin pérdida, desarrollado
por Terry Welch en 1984 y mejorado por Abraham Lempel y Jacob Ziv.
Utilizado en formato de imágenes de tipo *.TIFF, *.GIF y *.PNG.
“El
algoritmo busca patrones repetidos en la imagen y los reemplaza por códigos
de una tabla predefinida, asignando los códigos más cortos a los patrones o
secuencias más repetidos al igual que el algoritmo de Huffman.“ (Sánchez
Menéndez, 2012, p. 62)
2.1.2 Compresión con pérdida
Esta técnica de compresión maneja algoritmos que eliminan cierta parte de la
información de la imagen que puede ser imperceptible al ojo humano. Aplicando
este proceso se consigue un alto grado de compresión pero con la desventaja
que se pierden parte de los datos de la imagen y
por ende no se puede
reconstruir en forma exacta la imagen original.
Entre las técnicas de compresión con pérdida tenemos:

Compresión Fractal

Compresión por Wavelets

JPEG(Joint Photographic Experts Group - Grupo Conjunto de Expertos
en Fotografía)
De las tres técnicas de compresión antes mencionadas, la compresión JPEG se
implementó en el presente proyecto.
9
a) Compresión Fractal: Como su nombre lo indica está basado en fractales14.
Es una técnica bastante útil en imágenes que contienen texturas. Este
método asume que partes de la imagen se parecen a otras partes. Es decir
que para aplicar este método se divide a la imagen en pequeños bloques, se
toma uno de estos bloques como un patrón y se busca dentro de la imagen
otro similar para luego reemplazarlo mediante una ecuación matemática.
b) Compresión por Wavelets15: Utiliza la Transformada discreta de Wavelet.
Esta transformada descompone a una imagen en un conjunto de imágenes
pequeñas mediante la aplicación sucesiva de filtros pasa bajos y pasa altos.
Dada una imagen se aplican dos filtros: un filtro pasa bajo y otro pasa alto
obteniendo dos imágenes, seguidamente se diezma a cada una de las
imágenes verticalmente eliminando la columna de la mitad de la imagen.
Seguidamente se vuelve a aplicar los filtros en cada una de las imágenes y
por último se diezma cada una de las cuatro imágenes pero horizontalmente.
En la figura 2.3 y figura 2.4 se puede observar el proceso de descomposición
por Wavelets, donde los cuadros de color rojo representan los filtros pasa
alto y los azules representan los filtros pasa bajo.
Imagen
original
Figura 2.3 Esquema de descomposición una imagen por Wavelets.
14
Fractal, es un objeto geométrico cuya estructura básica, fragmentada o irregular, se
repite a diferentes escalas. (Mandelbrot)
15 (Fournier, Castro, Russo, & Bria)
10
Figura 2.4 a) Imagen Original, b) Descomposición de la imagen en wavelets.
(What-when-how, 2016)
c) Compresión JPEG: Es un estándar desarrollado conjuntamente por los
comités ISO (International Standarization Organization) y CCITT (Comitte of
the International Telephone & Telegraph). Pertenece a los algoritmos de
compresión con pérdida, es decir que al descomprimir la imagen esta no
tiene exactamente la misma calidad que la imagen original. “El algoritmo de
compresión JPEG se basa en dos fenómenos visuales del ojo humano: uno
es el hecho de que es mucho más sensible al cambio en la luminancia que
en la crominancia; es decir, capta más claramente los cambios de brillo que
de color. El otro es que nota con más facilidad pequeños cambios de brillo en
zonas homogéneas que en zonas donde la variación es grande; por ejemplo
en los bordes de los cuerpos de los objetos.” (Wikipedia, 2006)
En la figura 2.5 se observa el proceso de compresión JPEG.
Figura 2.5 Etapas del proceso de compresión JPEG
11
El proceso de compresión está dividido en las siguientes etapas:
1) Descomposición de la imagen en planos de color (RGB)
Las imágenes digitales están representadas por tres matrices, donde
cada una es la matriz correspondiente a cada plano de color (Rojo, Verde
o Azul).
“Desde el punto de vista del programador una imagen a color RGB es un
arreglo de tamaño MxNx3, donde MxN define las dimensiones de los
planos, mientras que la dimensión correspondiente a 3 define a cada uno
de los ellos R, G y B.” (Cuevas, Zaldivar , & Perez, 2010)
El modelo RGB es muy adecuado para representar imágenes en
monitores de computadoras, cámaras digitales, escáneres, etc. Es un
modelo de color básico, formado por la combinación de colores primarios:
Rojo, Verde y Azul. En la figura 2.6 se puede apreciar las componentes
de color de una imagen.
Normalmente los valores de cada componente de color son enteros
positivos que están en el intervalo [0,255] o en valores reales en el
intervalo [0,1]
Figura 2.6 Componentes de una imagen a color.
2) Cambiar el espacio de color de la imagen al espacio YCbCr16
El ojo humano es menos sensible a los matices de color que a la cantidad
de luz percibida. Es por esta razón que es de mucha importancia
convertir la imagen al espacio de color YCbCR ya que permite eliminar la
información innecesaria de la imagen separando la intensidad de los
colores de su tonalidad. En la figura 2.7 se observa la imagen en el
espacio de color YCbCr y sus respectivas componentes de color.
16
(Cuevas, Zaldivar , & Perez, 2010)
12
Figura 2.7 Descomposición de planos del espacio de color YCBCR.
El parámetro Y indica la Luminancia, es decir la imagen a escala de
grises, se encuentra en el intervalo [0,255] y los parámetros Cb y Cr
representan la Crominancia es decir la información con respecto al color:
la componente Cb, es la diferencia entre la componente azul y un valor
de referencia, y la componente Cr, es la diferencia entre la componente
roja y un valor de referencia. Estas componentes están en el intervalo de
[-128,127] con signo o [0,255] sin signo. Las ecuaciones para pasar del
modelo RGB al modelo YCBCR son:
( 2.1 )
𝑌(𝑥, 𝑦) = 𝑤𝑅 𝑅(𝑥, 𝑦) + (1 − 𝑤𝐵 − 𝑤𝑅 )𝐺(𝑥, 𝑦) + 𝑤𝐵 𝐵(𝑥, 𝑦)
0.5
(𝐵(𝑥, 𝑦) − 𝑌(𝑥, 𝑦))
1 − 𝑤𝐵
0.5
𝐶𝑟 =
(𝑅(𝑥, 𝑦) − 𝑌(𝑥, 𝑦))
1 − 𝑤𝑅
𝐶𝑏 =
Dónde:

𝑅(𝑥, 𝑦) es la componente de color rojo en la posición 𝑥, 𝑦

𝐺(𝑥, 𝑦) es la componente de color verde la posición 𝑥, 𝑦

𝐵(𝑥, 𝑦) es la componente de color azul en la posición 𝑥, 𝑦
En la ecuación 2.2 se describe el proceso inverso para pasar del modelo
RGB a YCBCR.
( 2.2 )
1 − 𝑤𝑅
𝐶𝑟
0.5
𝑤𝑅 (1 − 𝑤𝑏 )
𝑤𝐺 (1 − 𝑤𝐺 )
𝐺(𝑥, 𝑦) = 𝑌(𝑥, 𝑦) −
𝐶𝑏 −
𝐶
0.5(1 − 𝑤𝐵 − 𝑤𝑅 )
0.5(1 − 𝑤𝐵 − 𝑤𝑅 ) 𝑟
𝑅(𝑥, 𝑦) = 𝑌(𝑥, 𝑦) +
𝐵(𝑥, 𝑦) = 𝑌(𝑥, 𝑦) +
1 − 𝑤𝐵
𝐶𝑏
0.5
Dónde:

𝑌(𝑥, 𝑦) es la componente de la luminancia en la posición x, 𝑦

𝐶𝑏 (𝑥, 𝑦) es la componente de color azul la posición 𝑥, 𝑦

𝐶𝑟 (𝑥, 𝑦) es la componente de color rojo en la posición 𝑥, 𝑦
13
Para la transformación de modelos de color la Unión Internacional de
Telecomunicaciones (ITU) especifica los siguientes valores:
𝑤𝑅 = 0.299 𝑤𝐵 = 0.114 𝑤𝐺 = 0.587
Con los valores antes mencionados las matrices para la transformación
de modelo RGB a YCBCR y YCBCR a RGB respectivamente son las
siguientes:
( 2.3 )
𝑌(𝑥, 𝑦)
0.299
0.587
0.114 𝑅(𝑥, 𝑦)
[𝐶𝑏 (𝑥, 𝑦)] = [−0.169 −0.331 −0.500] [𝐺(𝑥, 𝑦)]
𝐶𝑟 (𝑥, 𝑦)
0.500 −0.419 −0.081 𝐵(𝑥, 𝑦)
( 2.4 )
𝑅(𝑥, 𝑦)
𝑌(𝑥, 𝑦)
1.000 0.000
1.403
[𝐺(𝑥, 𝑦)] = [1.000 −0.344 −0.714] [𝐶𝑏 (𝑥, 𝑦)]
𝐵(𝑥, 𝑦)
1.000 1.773
0.000 𝐶𝑟 (𝑥, 𝑦)
Los planos CbCr, de acuerdo a las transformaciones realizadas, pueden
contener valores tanto positivos como negativos, por esta razón se añade
un offset de 128 a los planos de color antes mencionados. Es decir la
ecuación (2.1) quedaría expresada de la siguiente forma:
( 2.5 )
𝑌(𝑥, 𝑦) = 𝑤𝑅 𝑅(𝑥, 𝑦) + (1 − 𝑤𝐵 − 𝑤𝑅 )𝐺(𝑥, 𝑦) + 𝑤𝐵 𝐵(𝑥, 𝑦)
0.5
(𝐵(𝑥, 𝑦) − 𝑌(𝑥, 𝑦)) + 𝟏𝟐𝟖
1 − 𝑤𝐵
0.5
𝐶𝑟 =
(𝑅(𝑥, 𝑦) − 𝑌(𝑥, 𝑦)) + 𝟏𝟐𝟖
1 − 𝑤𝑅
𝐶𝑏 =
3) Generar bloques de 8x8 para el procesamiento.
Antes de efectuar cualquier cálculo sobre la imagen, previamente se
debe dividir a cada plano de imagen en submatrices de 8x8 píxeles, estas
submatrices se denominan bloques. Para realizar este proceso se debe
tener en cuenta que las dimensiones de la imagen, deben ser múltiplos
de 8 tanto ancho como alto como se muestra en la figura 2.8, caso
contrario se debe realizar un proceso adicional para completar la imagen
tanto en filas como en columnas.
14
Figura 2.8 División de la imagen en bloques de 8x8 píxeles

Completar una imagen
Este proceso se debe aplicar únicamente a las imágenes que no
cumplan con el requisito de ser múltiplo de 8, en las dimensiones:
ancho y alto. Los pasos a seguir son los siguientes:

En el ancho de la imagen, se debe agregar las columnas
necesarias a la derecha de la imagen original hasta que su
ancho sea múltiplo de 8. Estas columnas se llenarán con los
mismos datos de la última columna.

De igual manera en el alto de la imagen se aumentan filas en
la parte inferior de la imagen original, estas filas contendrán
los datos de la última fila.
En la figura 2.9 se puede observar que la parte sombreada
representa una imagen de 10x13 píxeles. Dado que estas medidas no
son múltiplos de 8 se procede a aumentar las filas y columnas
respectivas.
Figura 2.9 Completar filas y columnas de una imagen
15
4) Transformada discreta de Coseno17 (DCT)
También llamada Transformada de Coseno es una transformada basada
en la transformada discreta de Fourier (DFT) con la diferencia que solo
trabaja con la parte real. Esta transformada es muy utilizada en la
compresión de imágenes, aplicaciones de video, teleconferencias y
televisión digital.
La transformada de coseno principalmente se aplica en la compresión de
imágenes JPEG, cuyo objetivo consiste en tomar los datos de la imagen
(muestras de dominio espacial), procesarlos y convertirlos en una
representación de dominio de frecuencias. Esta transformada trabaja con
las frecuencias presentes en una imagen, estas son: las frecuencias
bajas que representan el área más sensitiva al ojo humano, y las
frecuencias altas que son menos sensibles al ojo. En la figura 2.10 se
muestra como se distribuyen las frecuencias en una imagen.
Altas
frecuencias
Bajas
frecuencias
Altas
frecuencias
Figura 2.10 Representación de las frecuencias de una imagen (SlideShare, 2016)
Este proceso se aplica para cada uno de los componentes de la imagen y
a su vez cada uno de los bloques 8x8. Para ello se multiplica cada píxel
del bloque por términos que representan ondas de coseno, seguidamente
se realiza una suma secuencial con el resultado del cálculo antes
mencionado, obteniendo una nueva matriz con 64 elementos por cada
bloque. Estos elementos se dividen en dos partes: el elemento de la
esquina superior izquierda de la imagen esta la frecuencia más baja
denominada DC o frecuencia cero y alrededor de este se dispersan los
63 coeficientes restantes que son las frecuencias altas denominadas AC.
17
(Esqueda Elizondo & Palafox Maestre, 2005)
16
En la figura 2.11, se muestra que la concentración de la energía se
encuentra en la esquina superior izquierda de la imagen.
Figura 2.11 Compactación de la energía DCT (Wikipedia, 2016)
El proceso que realiza la DCT es de gran utilidad ya que ordena los
coeficientes de la imagen de forma adecuada en frecuencias altas y bajas
facilitando la eliminación de las frecuencias bajas que se realiza en el
siguiente paso que es la Cuantización.
La ecuación 2.6 define la DCT:
( 2.6 )
𝐷𝐶𝑇(𝑢, 𝑣) =
𝑁−1 𝑁−1
(2𝑥 + 1)𝑢𝜋
(2𝑦 + 1)𝑣𝜋
𝐶𝑢 𝐶𝑣 ∑ ∑ 𝐼(𝑥, 𝑦) cos [
] cos [
]
2𝑁
2𝑁
√2𝑁
1
𝑥=0 𝑦=0
Dónde:
1
𝐶𝑢 , 𝐶𝑣 = {√2
1
𝑢, 𝑣 = 0
𝑜𝑡𝑟𝑜𝑠 𝑐𝑎𝑠𝑜𝑠
𝑢, 𝑣 = 0,1, … , 𝑁

𝐼(𝑥, 𝑦) representa los datos de la imagen en la fila (x) y
columna (y)

𝑁 es el tamaño del bloque, en este caso N es 8
De igual forma para reconstruir la imagen se cuenta con
la
Transformada Inversa de Coseno que viene dada por la siguiente
expresión matemática:
( 2.7 )
17
𝐼(𝑥, 𝑦) =
𝑁−1 𝑁−1
(2𝑥 + 1)𝑢𝜋
(2𝑦 + 1)𝑣𝜋
𝐶𝑢 𝐶𝑣 ∑ ∑ 𝐷𝐶𝑇(𝑢, 𝑣) cos [
] cos [
]
2𝑁
2𝑁
√2𝑁
1
𝑥=0 𝑦=0
Dónde:

𝐷𝐶𝑇(𝑥, 𝑦) representa los datos de la transformada de coseno

𝑁 es el tamaño del bloque, en este caso de N es 8
5) Cuantización18
Es una técnica que se utiliza en la compresión de imágenes JPEG y se
aplica luego de emplear la Transformada Discreta de Coseno.
Este proceso también se aplica en matrices (bloques 8x8) resultantes de
la DCT y divide cada componente de los bloques para cada componente
de la matriz de cuantificación y se redondea a su entero más cercano.
Las matrices de cuantificación estandarizadas para los diferentes planos
de color se muestran en la tabla 2.1.
16
12
14
14
18
24
49
[72
11
12
13
17
22
35
64
92
10
14
16
22
37
55
78
95
24 40
16
26 58
19
24
40 57
29
51 87
56 68 109
64 81 104
87 103 121
98 112 100
17
51 61
18
60 55
24
69 56
47
80 62
99
103 77
99
113 92
99
120 101
[
]
99
103 99
a)
18
21
26
66
99
99
99
99
24
26
56
99
99
99
99
99
47
66
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
80
99
99
99
99
b)
Tabla 2.1 Matrices de Cuantización: a) Luminancia, b) Crominancia
En resultado de este proceso elimina las componentes de altas
frecuencias, es decir tienden a igualarse a cero, mientras que las demás
componentes se reducen a números pequeños.
6) Recorrido en zigzag
En este paso se construye un vector de 64 elementos para cada uno de
los bloques anteriormente procesados. En cada bloque se hace un
recorrido en forma de zigzag como se visualiza en la figura 2.12 y se
obtiene un vector en cada bloque de la imagen.
18
(SlideShare, 2011)
18
99
99
99
99
99
99
99
99]
Figura 2.12 Recorrido de un bloque en zigzag
7) Codificación RLE
Utilizando el vector obtenido en el paso anterior, se procede a aplicar el
método RLE (explicado en la sección compresión sin pérdida), se utiliza
las misma lógica pero en vez de contar los elementos repetidos en este
caso se cuentan los ceros que anteceden a determinado elemento
distinto de cero. Los datos se almacenan de tal manera que se tiene una
serie de pares (número de ceros que anteceden, valor distinto de cero).
Utilizando el vector de la figura 2.12, se obtienen los pares de elementos
mostrados en la siguiente figura.
(0,5)
(0,2)
(0, -21)
DC
(0,-8)
(5,-3)
(54,0)
AC
Figura 2.13 Vector con pares, luego de aplicar RLE
8) Codificación de Huffman19
El objetivo de la Codificación de Huffman es reducir la cantidad de bits
necesarios para representar los datos de los bloques anteriormente
cuantificados. Para llevar a cabo esta codificación se utilizan las tablas
estandarizadas que se detallan más adelante, donde determinado valor
de cada uno de los bloques poseen una categoría determinada y una
determinada representación en binario.
Este proceso se ejecuta en dos partes:
19

Codificación para los coeficientes AC

Codificación para los coeficientes DC
(Carrillo, 2002)
19
A continuación se presentan dos tablas que se utilizan para la
codificación de coeficientes AC.
La tabla 2.2 contiene la categoría y bits que se debe agregar a un
determinado par de elementos.
Categoría
Bits adicionales
1
Valores incluidos
en la categoría
-1,1
2
-3,-2,2,3
00, 01, 10, 11
3
-7,…,-4,4,…,7
000,…,011,100,…111
4
-15,…,-8,8,…,15
0000,…,0111, 1000,…,1111
5
-31,…,-16,16,…,31
6
-63,…,-32,32,…,63
7
-127,…,-64,64,…,127
8
-255,…,-128,128,…,255
9
-511,…,-256,256,…,511
10
-1024,…,-512,512,…
0,1
Tabla 2.2 Categorías y bits adicionales para los coeficientes AC
En la tabla 2.3, se muestra el contenido parcial de la codificación de
Huffman. Donde la iniciales R/C, representan R: número de ceros que
anteceden a determinado elemento y C: representa la categoría a la que
pertenece.
R/C
EOB
0/1
0/2
0/3
0/4
0/5
…
1/1
1/2
1/3
1/4
1/5
…
2/1
Dimensión
código
4
2
2
3
4
5
…
4
5
Código
…
5
…
11100
20
1010
00
01
100
1011
11010
…
1100
11011
2/2
2/3
2/4
2/5
…
3/1
3/2
3/3
3/4
3/5
…
4/1
4/2
4/3
4/4
4/5
…
5/1
5/2
5/3
5/4
EOB
0/1
0/2
0/3
0/4
0/5
8
10
11111011
1111110111
…
6
9
12
…
111010
111110111
111111110101
…
6
10
16
…
1111011
1111111000
1111111110010110
…
7
11
16
…
1111010
11111110111
1111111110011110
4
2
2
3
4
5
1010
00
01
100
1011
11010
Tabla 2.3 Contenido parcial para la Codificación de Huffman.

Codificación de los coeficientes AC
Teniendo en cuenta el par de elementos que se obtuvo en la compresión
RLE, se realiza los siguientes pasos:

Se analiza el primer par AC, del cual se toma el elemento de la
segunda componente, este valor se verifica a que intervalo de la
segunda columna de la Tabla 2.2 pertenece; además se obtiene
de la tercera columna el código que representa al mismo valor
que en este caso lo llamaremos código1 y por último se obtienen
los valores de R/C, R viene a ser el valor del primer elemento del
par evaluado y C, es la categoría correspondiente al segundo
elemento del par evaluado.

Utilizando los valores R/C, se verifica en la Tabla 2.3 el código
que le corresponde, en este caso lo denominamos código2.
21

Por último se concatenan los códigos (código2 y código1)
obtenidos anteriormente para formar una cadena de bits que
representa el par evaluado.
El proceso antes descrito se realiza en cada uno de los bloques de la
imagen.
Aplicando este proceso a los datos de la figura 2.13, se obtienen los
siguientes resultados.
Tabla 2.4 Ejemplo Codificación de Huffman para coeficientes AC

Codificación para los coeficientes DC
Dado que los coeficientes DC representan el promedio de intensidad de
cada bloque, son valores muy grandes. Por ende se debe realizar un
proceso adicional para reducir dichos valores. Este proceso se denomina
codificación DPCM20 (Differential Pulse Code Modulation – Codificación
modulada de los pulsos diferenciales) que consiste en restar los valores
DC de cada bloque, es decir se realiza una resta entre el valor DC del
bloque actual y el valor DC del bloque anterior. Únicamente en el caso
del primer bloque al valor DC se resta de cero, que nos da como
resultado el mismo valor. Los valores obtenidos al realizar estas restas se
almacenan en un vector, para posteriormente utilizar estos datos en la
Codificación de Huffman de valores DC.
Figura 2.14 Codificación DPCM en bloques de imagen. (Martín M. , 2004)
20
(Pap, 2005)
22
A continuación se muestran dos tablas: tabla 2.5 y tabla 2.6 que se
utilizan para realizar la codificación de coeficientes DC.
Categoría
Bit adicionales
0
Valores incluidos
en la categoría
0
1
-1,1
0,1
2
-3,-2,2,3
00, 01, 10, 11
3
-7,…,-4,4,…,7
000,…,011,100,…111
4
-15,…,-8,8,…,15
0000,…,0111, 1000,…,1111
5
-31,…,-16,16,…,31
6
-63,…,-32,32,…,63
7
-127,…,-64,64,…,127
8
-255,…,-128,128,…,255
9
-511,…,-256,256,…,511
10
-1024,…,-512,512,…
-----
Tabla 2.5 Categorías y bits adicionales para los coeficientes DC
Categoría Dimensión del
código
0
2
Código
00
1
3
010
2
3
011
3
3
101
4
3
101
5
3
110
6
4
1110
7
5
111110
8
6
1111110
9
7
1111110
10
8
11111110
Tabla 2.6 Codificación de Huffman de coeficientes DC
Empleando el vector obtenido al aplicar la codificación DPCM, se procede
a calcular los respectivos Códigos de Huffman. Este proceso se realiza
en forma similar a la codificación para coeficientes AC, empleando las
Tablas 2.5 y 2.6.
23
Utilizando el ejemplo de la Figura 2.13 el valor DC es 5, asumiendo que
este dato pertenece al primer bloque de la imagen. Su codificación sería:
Segundo
Código
Código1 Categoría Código2
elemento
completo
(0,5)
5
101
3
101
101101
Par
Tabla 2.7 Ejemplo de Codificación de coeficientes DC
Finalmente se unen todos los códigos obtenidos en cada bloque es decir
el código de los coeficientes AC con el código del coeficiente DC
respectivamente de cada bloque.
Del ejemplo antes expuesto y empleando las Tablas 2.4 y 2.7 que tiene
la siguiente cadena de bits resultante.
101101
(0,5)
𝐶𝑜𝑒𝑓𝑖𝑐𝑖𝑒𝑛𝑡𝑒
𝐷𝐶
0110 1101001010 10110111 1111111011100 1010
(0, −8)
(5, −3)
(0,63)
(0,2)
(0, −21)
𝐶𝑜𝑒𝑓𝑖𝑐𝑖𝑒𝑛𝑡𝑒𝑠 𝐴𝐶
Figura 2.15 Código de Huffman de un bloque de imagen.
2.2 Descompresión
El proceso de descompresión se utiliza para reconstruir la imagen. Esto
se lleva a cabo empleando el mismo proceso que el de la compresión
pero en forma inversa. Se parte desde el último proceso de compresión
hasta llegar a obtener la imagen en el espacio de color RGB.
1) Recuperar los coeficientes cuantificados AC y DC
Para recuperar estos coeficientes se utilizan las mismas tablas
empleadas en la codificación de Huffman.

Se procede a realizar una búsqueda del código y para ello se
toman los dos primeros bits de la cadena y se va agregando un bit
hasta que la comparación sea exitosa.

Una vez que ya se haya encontrado el primer código, en nuestro
caso lo llamamos código2 se determina el valor al que
representa.
24

Con este valor se deduce la categoría a la que pertenece y la
dimensión que tiene el código1, es decir con este dato ya se
sabe cuántos bits se deben tomar en próximo recorrido.
Este proceso se realiza hasta finalizar la cadena de bits, obteniendo
así un vector con dos elementos.
Por último en el caso de la componente DC además de encontrar el
valor correspondiente se debe realizar una suma con los coeficientes
DC empleado la lógica de la codificación DPCM.
Se tiene como resultado un vector que en cada posición almacena un
par de elementos.
2) Recorrido inverso en zigzag
Utilizando el vector anterior, se procede a colocar cada uno de los datos
en cada posición del bloque 8x8, realizando un recorrido en zigzag en
cada uno de ellos hasta almacenar el último término.
3)
Proceso Inverso de la Cuantificación
A pesar de que el proceso de cuantificación es un proceso irreversible se
puede recuperar una aproximación de los valores de la DCT. Para esto
se realiza una multiplicación entre la matriz (bloque 8x8) obtenida
anteriormente y una de las matriz de cuantificación estandarizadas
correspondiente al plano de color que se esté procesando.
4) Proceso Inverso DTC
Este proceso se realiza empleando la Ecuación 2.7 en cada uno de los
bloques de la imagen. De esta forma se obtiene los valores de cada
componente del espacio de color YCbCr.
5)
Conversión al espacio de color RGB
Por último solo resta pasar del espacio de color YCbCr al espacio de
color RBG y para ello se utiliza la Ecuación 2.2.
Finalmente se obtiene una nueva imagen en formato JPG que a
percepción del ojo humano es similar a la imagen original, con la
diferencia que esta nueva imagen posee un menor peso.
Cabe aclarar que el formato JPEG o JPG es lo mismo, “... la diferencia
está en que en algunos sistemas operativos solo aceptan tres letras de
25
extensión.” (García, 2006) . La extensión JPEG generalmente se utiliza
en MAC y la extensión JPG se utiliza en Windows.
26
3. METODOLOGÍA
El desarrollo de este proyecto se basa en la metodología de Pressman21 que se
divide en 5 fases:
a) Análisis de los requisitos del software: En esta etapa se define la
funcionalidad de la aplicación, además las tecnologías y herramientas
que son de utilidad para la implementación de la misma.
b) Diseño: Se realizan diferentes tipos de diagramas para representar la
navegación, estructura e interfaz de la aplicación.
c) Generación de Código: Se refiere tanto a la parte de generación de los
ambientes virtuales, como
a la parte en la
cual se añadirá
comportamiento a estos ambientes.
d) Prueba: Se evalúa la aplicación mediante pruebas reales tanto en la
estructura como en la funcionalidad.
e) Mantenimiento: El software indudablemente sufrirá cambios, y habrá
que hacer algunas modificaciones a su funcionalidad.
De estas fases, se descarta la última etapa debido a que no se ajusta
completamente al proyecto planteado. A continuación de describe cada una de
las etapas desarrolladas en el presente proyecto:
3.1 Análisis de los requisitos del software
La aplicación web está diseñada para cargar una imagen, la cual se someterá al
proceso de compresión imágenes, y pocos segundos después se retornará la
imagen comprimida, es decir la interfaz mostrará la imagen original y la
reconstruida.
Las imágenes que se admiten deben tener las siguientes características:

Imágenes pequeñas (256x256) e imágenes medianas (800x500).

Formatos bmp, tiff, png, jpg, gif
La aplicación web estará compuesta por tres páginas:

La primera, que contenga una breve introducción de la funcionalidad de
la aplicación.
21
(Barrios, León, & Romero, 2016)
27

La segunda, una pantalla que permita cargar imágenes y poco después
que retorne la imagen comprimida.

La tercera, que presente información acerca del desarrollo la aplicación.
Además se debe tener en cuenta que para el desarrollo del proyecto se empleó
una Portátil con las siguientes características:

Procesador 2.20Hz

Memoria RAM 8GB

Disco duro 1TB

Sistema operativo Windos7
En base a los requisitos anteriormente expuestos de utilizó Visual Studio
2013(versión estable), como entorno de desarrollo y ejecución.
Visual Studio22: Es un entorno de desarrollo integrado (IDE), proporcionado por
la compañía Microsoft. Es una herramienta multilenguaje ya que permite
desarrollar en varios lenguajes como: C++, C#, Visual Basic .NET, etc., además
de ASP .NET que está orientado al desarrollo web. Dispone de un conjunto de
herramientas de programación para la generación de aplicaciones de escritorio,
aplicaciones
web,
Servicios Web
XML
y
aplicaciones
móviles.
Estas
herramientas son las siguientes:

Editor de código fuente: Es un editor de texto que permite editar código
fuente en un lenguaje determinado como: C++, C#, HTML, CSS o
JavaScript, etc.

Un compilador: Convierte el código fuente en lenguaje de máquina.

Un depurador: Su función es probar y eliminar posibles errores en un
programa en desarrollo.

Constructor de interfaz gráfica: Se utiliza para crear, diseñar y
especificar la ubicación de los controles y otros elementos que permiten
la interacción entre la aplicación y el usuario.
El desarrollo del proyecto se dividió en dos partes:

Primero se implementó una librería que efectúa el proceso de compresión
de imágenes basado en la técnica de compresión JPEG.

Segundo, se crea una interfaz de usuario que se adapte al proceso de
compresión.
22
(Msdn.microsoft.com, 2016)
28
3.1.1 Librería de compresión
Se utilizó como lenguaje de desarrollo a C Sharp(C#) junto con algunas librerías
que permiten el manejo de imágenes digitales.
a) C Sharp23 (C#): Es un lenguaje de programación creado por el danés Anders
Hejlsberg y estandarizado por Microsoft como parte de la plataforma .NET.
Está diseñado para crear aplicaciones de escritorio, aplicaciones web y
móviles. Utiliza sintaxis que se deriva de C/ C++, lo que facilita la migración
de código entre estos lenguajes. Posee las siguientes características:

Sencillo: Elimina elementos que otros lenguajes crean y no son
necesarios.

Alto nivel: Es independiente de la arquitectura del ordenador. Es un
lenguaje muy similar al lenguaje natural, esto quiere decir que para
ejecutar un programa un compilador se encarga de convertirlo en
lenguaje de máquina.

Orientado a objetos: Permiten estructurar programas de una forma
más ordenada, para ello utiliza objetos, compuestos por atributos y
métodos propios de cada clase. Además cuenta con características
de encapsulación, herencia y polimorfismo.

Administración de memoria: Es muy útil ya que gracias a esta
característica los programas pueden liberar memoria de forma
automática, es decir que no es necesario crear destructores de
objetos.

Compatible: Facilita la migración a otros lenguajes como: C, C++ y
Java ya que tienen una sintaxis muy similar.
b) System.Drawing24: Permite el manejo de imágenes mediante las clases
Bitmap y Color. Es decir se puede acceder a los atributos de una imagen
como son: su tamaño y la información que está contenida en cada píxel de la
imagen.
-
Clase Bitmap: Esta clase permite manipular imágenes. Para inicializar
un constructor de tipo Bitmap, que se requiere como parámetro de
entrada la ruta de la imagen.
23
24
(C Sharp - EcuRed, 2016)
(Besteiro & Rodríguez )
29
Bitmap img = new Bitmap(@"C:\Users\dell\Documents
\IMAGENES\img1.jpg");
-
Clase Color25: Se utiliza para acceder a la información del color en cada
píxel de la imagen. La estructura Color está representada por un color de
tipo ARGB (Alpha, Red, Green, Blue), donde:

A representa la componente de la opacidad

R representa la componente de color rojo

G representa la componente de color verde

B representa la componente de color azul
Cada uno de los colores anteriores está en el intervalo de 0 a 255.
Para manipular los datos de la imagen se tienen los siguientes métodos
GetPixel, se utiliza para obtener los datos de la imagen en una
determinada posición.
Color pixelColor = img.GetPixel(x, y);
SetPixel, se utiliza para modificar los datos de la imagen en una
determinada posición.
Color nuevoColor = Color.FromArgb(30, 0, 0);
img.SetPixel(x, y, nuevoColor);
c) System.Collections.Generic: Esta librería es usada para trabajar con
estructuras de datos, en este proyecto se utilizó la estructura List.
-
List26: Es una estructura dinámica en la que se puede ir agregando o
quitando elementos. Estos elementos pueden ser agregados al principio,
al final o en la mitad de una lista. Proporciona métodos para buscar,
ordenar y manipular elementos de la lista. El acceso a los elementos de
una lista se lo hace mediante el uso de un índice.
En el presente proyecto se utilizaron listas para la implementación del
método de compresión RLE, a continuación se describe un ejemplo:

Inicializar una estructura de tipo List
List<Point> elementos = new List<Point>();
Tipo de dato
25
26
(Msdn.microsoft, 2016)
(Nachocabanes.com, 2010)
30

Agregar elementos a la lista
Point datos = new Point();
datos.X = cont; datos.Y = aux1;
elementos.Add(datos);
3.1.2 Aplicación web
En el desarrollo de la interfaz de la Aplicación web se utilizaron las siguientes
herramientas:
a) ASP.NET27: Es una tecnología que permite crear páginas web dinámicas que
se ejecutan en el servidor. El servidor que utiliza es IIS (Internet Information
Service) que viene incorporado en el Sistema operativo de Windows y se
comunica con la capa cliente utilizando el protocolo HTTP.
Características de Asp.net:

Facilita la realización de tareas comunes como envío de formularios y
la autenticación del cliente.

Está conformado por Web Forms que permiten separar la interfaz de
usuario de la funcionalidad de la aplicación.

Gestión automática de memoria con recolección de basura.

Es multilenguaje ya que para desarrollar aplicaciones puede emplear
cualquier lenguaje de programación admitido por la plataforma .NET.

Para mejorar el rendimiento de las aplicaciones compila el código
solo la primera vez que algún cliente lo solicite y así el resto de
peticiones del mismo se atenderán de forma más ágil.
En el presente proyecto, la interfaz de usuario se diseñó mediante
formularios, Web Forms que reemplazan a las páginas de tipo HTML.
Además se utilizaron las siguientes librerías:

System.Drawing.Imaging: Se utiliza para para establecer el tipo de
formato de una imagen.

System.IO: Esta librería se utiliza para el manejo de archivos, es
decir permite crear, mover o almacenar archivos en una ruta
determinada. En este caso para almacenar las imágenes que son
subidas al servidor.
27
(Guérin, 2014)
31
De igual forma se utilizaron las siguientes tecnologías para la estructura de la
Aplicación Web:
b) JavaScript28: Es un lenguaje de programación interpretado, multiplataforma
y orientado a objetos, utilizado para el desarrollo de aplicaciones web, tanto
en la parte del cliente como en la del servidor. Este lenguaje permite dar
funcionalidad a los objetos dentro de la aplicación o sitos web. Es dinámico
ya que responde a eventos que son producidos por el usuario en tiempo real.
Estos eventos pueden ser presionar un botón, validación de formularios, etc.
c) CSS29: Se conoce como hojas de estilo en cascada. Es una tecnología que
permite controlar el diseño y la estética de un sitio o aplicación web. Permite
dar formato a la página web, por ejemplo modificar estilos como: el tipo,
tamaño y color de la fuente, establecer márgenes, color de fondo de la
página, interlineados de párrafo, etc. Estos estilos se pueden incorporar de la
siguiente forma:

CSS in line, es decir insertar el estilo CSS directamente dentro de la
etiqueta HTML
<p style="color: red;">párrafo</p>

Hoja de estilos interna, significa agregar el estilo CSS dentro del
mismo archivo HTML, pero empleando etiquetas
<head>
<style type="text/css">
Aquí van los estilos
</style>
</head>

Hojas de estilo externas, es decir crear un archivo aparte guardado
con la extensión .CSS. Este archivo se debe importar en el
encabezado de la página donde se va a utilizar los estilos
incorporados en la hoja de estilo.
En el presente proyecto se utiliza la última opción, es decir Hojas de
estilo externas, esto ayuda a tener por separado el lado estético de la
Web y de esta forma la estructura de la aplicación está mejor organizada.
28
29
(Berzal, Cortijo, & Cubero)
(Barcia, 2003)
32
d) HTML530: Es una versión de HTML que conjuntamente con las tecnologías
CSS y JavaScript permite la creación de sitios y aplicaciones web. Incorpora
nuevos elementos multimedia como audio, video que pueden ser incrustados
de
forma
más
sencilla,
simplemente
empleando
las
etiquetas
<video></video> y <audio></audio> respectivamente. Es decir que
para visualizar un video ya no es necesario instalar el plugin de adobe flash
player, simplemente basta con disponer de un navegador compatible con
HTML5. Además otra etiqueta destacada es el <canvas></canvas> que
permite crear un área de dibujo rectangular donde se puede dibujar líneas,
rectángulos, etc; también manipular imágenes y crear animaciones mediante
la programación en JavaScript.
En este proyecto de utilizó la etiqueta input de type="file", que permite
la entrada y previsualización de archivos como imágenes y texto. Estos
archivos pueden ser seleccionados de forma individual o múltiple. En este
caso particular se empleó para subir imágenes de forma individual. A
continuación se muestra la etiqueta con sus respectivas características:
<input id="Upload" type="file" class="upload" />
e) AJAX31: Javascript y XML Asíncrono, es una técnica de JavaScript que se
emplea para intercambiar información entre un servidor y el cliente sin
necesidad de recargar la página. Ajax es bastante útil en páginas que
manejan gran cantidad de datos o a su vez que son usadas por un buen
número de personas. Utiliza los siguientes parámetros:

type: se especifica el tipo de petición GET o POST

url: se edita el nombre de la página a la que van a ser enviados los
datos.

data: se especifica la información que será enviada al servidor en
forma de una cadena de texto, es decir un dato de tipo String.

succes: Este evento se ejecuta en caso de que la petición se ha
realizado con éxito.
Esta técnica se utilizó para subir imágenes del cliente al servidor y a su vez
para retornar la imagen comprimida al cliente.
30
31
(Exp3rto, 2014)
(LIBROSWEB)
33
Para alojar la aplicación web, se empleó el servidor descrito a continuación:
f) IIS32 (Internet Information Server): Es un conjunto de servicios web que
hacen que un ordenador se convierta en un servidor web. Este servidor web
viene por defecto en el paquete de Windows 7 profesional y se emplea para
la creación, hospedaje, configuración y administración de sitios y
aplicaciones web.
Los principales servicios de IIS son:

FTP: Permite transferir archivos en una arquitectura cliente servidor,
es decir que los usuarios pueden subir o a su vez descargar archivos
del lado del servidor.

SMTP: Permite intercambiar mensajes de correo electrónico entre los
ordenadores.

NNTP: Protocolo de transferencia de noticias en la red, como su
nombre lo indica permite la lectura y publicación de noticias.

HTTP: Protocolo de transferencia de hipertexto. Este protocolo
permite el intercambio de información hipertextual (enlaces) de las
páginas web.
32
(Scribd, 2016)
34
3.2 Diseño
En esta etapa se realizaron diferentes diagramas para representar la estructura y
el funcionamiento de la Aplicación Web desarrollada.
INICIO
Leer imagen
Mostrar imagen en
pantalla
Proceso compresión
Proceso descompresión
Mostrar imagen
comprimida
FIN
Figura 3.1 Diagrama de flujo de la aplicación.
3.2.1 Diagrama de clases para la Librería desarrollada
a) En la siguiente figura se puede observar el proceso completo
para
realizar la compresión JPEG, además como están relacionadas cada una
de las clases.
35
Figura 3.2 Diagrama de clases Librería de compresión de imágenes, método JPEG.
b) Se parte de una clase Imagen, la cual permite obtener el alto, ancho y los
datos de las diferentes componentes de la imagen, mismos que se utiliza
en la clase CompresionJPEG.
Figura 3.3 Relación entre las clases: Imagen y CompresionJPEG
c) Las clases: Bloque y MatrizBloque realizan la mayor parte de los cálculos
de la compresión.
36
Figura 3.4 Diagrama de clases: Bloque y MatrizBloque
3.2.2 Diagrama para la Aplicación Web
En un principio la aplicación cuenta con una página principal, y tres subpáginas
como se visualiza en el siguiente esquema:
Página principal
Descripción
Aplicación
Documentación
compresión
Figura 3.5 Esquema de aplicación web
a) Página principal, está conformada por cuatro botones que permiten
acceder a los formularios Descripción, Aplicación y Documentación.
b) Descripción, esta página contiene información acerca de la Aplicación
desarrollada.
37
c) Aplicación, este formulario es el más importante ya que contiene la
implementación de la Librería desarrollada.
d) Documentación, presenta una breve descripción de las clases más
importantes de la Librería y tiene un botón que permite descargar el
proyecto completo.
Para la implementación de la Aplicación Web se creó en un proyecto en
ASP.NET, el cual está conformado por cinco formularios como se visualiza en la
figura 3.7.
Figura 3.6 Diagrama de clases de la Aplicación Web
38
3.3 Generación de código
En esta etapa se desarrollaron diferentes clases y métodos para la creación de
la Librería de compresión de imágenes y la Aplicación Web. A continuación se
describen los más importantes:
3.3.1 Librería de compresión de imágenes
a) Clase Imagen: Esta clase tiene como atributos tres variables de tipo matriz
que son los planos de color de la imagen: r (rojo), g (verde), b (azul),
adicionalmente ancho y alto que representan las dimensiones de la imagen
respectivamente.
Esta clase cuenta con los siguientes métodos:

ObtenerPlanos(Bitmap imagen): Recibe como parámetro de
entrada un Bitmap. Este
método se utiliza para descomponer la
imagen sus componentes de color: Rojo, Verde y Azul.

ReconstruirImagen
(double
[,,]matImg):
Permite
reconstruir una imagen a partir de uan matriz que tiene tres
componetes, es decir los canales de color:rojo, verde y azul.

ConvertiRGBaYCBCR(): Este método permite la conversión del
espacio de color RGB al espacio de color YCBCR.

ConvertirYCBCRaRGB(): Realiza el proceso inverso del anterior
método.
b) Clase Bloque: En esta clase es donde se realiza la mayor parte de los
cálculos de la compresión JPEG. Para ello define una matriz de 8x8
denominado bloque y sobre el cual se realizan las siguientes métodos:

TDC(), ITDC(): Se utilizan para calcular la Transformada de
Coseno y su inversa en un bloque dado.

Cuantizar(),
InvCuantizar():
Permite
calcular
la
cuantificación y su inversa respectivamente de un determinado
bloque. Para ello utiliza las matrices estandarizadas que son
Luminancia y
Crominancia para cada componente de color
respectivamente.

RecorrerZigZag(): Recorre los datos de un bloque en forma de
zigzag y de vuelta retorna un vector con 64 elementos.
39
c) Clase MatrizBloque: Esta clase hereda la mayoría de los métodos de la
clase Bloque y se utiliza para realizar los cálculos sobre toda la imagen.
d) Clase CompresionJPEG: Esta clase emplea los métodos de la clase
MatrizBloque para realizar el proceso de compresión. Consta de un
constructor que recibe como parámetro de entrada un Bitmap.

CompresionJPEG(Bitmap
Imagen):
Este
constructor
internamente realiza el procesamiento de la imagen que fue subida al
servidor y para ello emplea los siguientes métodos:

CompresionImagen(Imagen
img): Permite realizar la
compresión de la imagen y requiere como parámetro de
entrada un objeto de tipo Imagen, posteriormente retorna una
matriz con tres componentes.

DescompresionImagen(double
[,,]
imgCompress):
Recibe los datos de la imagen comprimida y procede a
realizar el proceso inverso para poder mostrar la imagen en
pantalla.
3.3.2 Aplicación Web
La mayor parte del desarrollo de la Aplicación Web se encuentra en el formulario
de nombre Aplicación. En este formulario está compuesto por dos botones, uno
que permite subir la imagen y otro que se usa para descargar la imagen una vez
que se haya realizado el proceso de compresión.
Para subir la imagen al servidor, se empleó un Controlador Genérico más
conocido como Handler que permite obtener y enviar datos entre cliente y
servidor utilizando la tecnología AJAX.
En la clase Handler, denominada SubirArchivo, se recibe y envían los datos de la
imagen mediante el método ProcessRequest(HttpContext context).
Para ello emplea los siguientes objetos:

Request, permite el acceso a toda la información que pasa desde
el navegador del cliente al servidor.

Response, permite enviar datos al cliente como respuesta a una
petición realizada.
A continuación se muestra como se utilizaron los objetos en el presente
proyecto.
Para obtener los datos de la imagen que sube el cliente al servidor:
40
context.Request["Image"];
De igual forma para enviar los datos de la imagen al cliente se utiliza el siguiente
código.
context.Response.Write(base64);
donde Image representa los datos de la imagen codificados en Base64. Este
dato se procede a decodificar con los métodos que se describen a continuación:

Base64ToBitmap(String
Base64), este método recibe como
parámetro de entrada un String de tipo Base64, y procede a convertirlo
en un Bitmap.

BitmapToBase64(Bitmap imagen), realiza el proceso inverso del
anterior método, es decir a partir de un Bitmap se retorna un String de
tipo Base64.
Para enviar la imagen del lado del cliente se utiliza un archivo JavaScript,
denominado aplicacion.js, en el que se utilizó la técnica AJAX, de la siguiente
forma:
Variable que se recibe en el
Handler
var Img = { Image: datos_img, Nombre: file.name };
$.ajax({
url: 'SubirArchivo.ashx',
Nombre de la página a la que
se envían los datos
type: 'POST',
data: Img,
Datos a enviar
success: function (data) {
img_compress.src =
'data:image/jpg;base64,'+data;//ASIGNA LA CADENA
BASE64 AL LA IMAGEN_COMPRIMIDA
alert("LA IMAGEN HA SIDO CARGADA EXITOSAMENTE");
},
error: function(){alert("ERROR AL INTENTAR SUBIR
LA IMAGEN. VUELA A INTENTAR")}
});
Evento que se ejecuta luego
que la solicitud ha sido
satisfactoria
41
4. PRUEBAS Y RESULTADOS
En este capítulo se describen las pruebas realizadas para verificar el
funcionamiento de la Librería y Aplicación Web desarrollada.
En primer lugar se obtuvieron imágenes de diferentes páginas web que publican
Bases de datos (Dataset) de imágenes que no presentan ningún preprocesamiento. A continuación se presenta una lista con las fuentes antes
mencionadas:

Imágenes .TIFF
G. Schaefer and M. Stich (2004) "UCID - An Uncompressed Colour
Image Database", Proc. SPIE, Storage and Retrieval Methods and
Applications for Multimedia 2004, pp. 472-480, San Jose, USA. Esta
página
la
podemos
encontrar
en
el
siguiente
link:
http://homepages.lboro.ac.uk/~cogs/datasets/ucid/ucid.html

Imágenes .PNG
V. Christlein, C. Riess, J. Jordan, C. Riess, E. Angelopoulou: "An
Evaluation of Popular Copy-Move Forgery Detection Approaches", IEEE
Transactions on Information Forensics and Security, vol. 7, no. 6, pp.
1841-1854, 2012. Se puede tener acceso a las imágenes desde la
siguiente dirección web: https://www5.cs.fau.de/research/data/imagemanipulation/

Imágenes .GIF BINARIAS, .TIFF ESCALA DE GRISES
ImageProcessingPlace.com, para tener acceso a las imágenes visitar la
dirección web:
http://www.imageprocessingplace.com/root_files_V3/image_databases.ht
m

Imágenes .JPG
Herve Jegou, Matthijs Douze and Cordelia Schmid
"Hamming Embedding and Weak geometry consistency for large scale
image search" Proceedings of the 10th European conference on
Computer
vision,
October,
2008.
http://lear.inrialpes.fr/~jegou/data.php
42
Revisar
el
siguiente
link:
Por otra parte para determinar el nivel de compresión y calidad de las imágenes
se realizó un estudio de métricas de calidad. A continuación se describe cada
una de ellas:
1. Ratio de Compresión: Es la relación que existe entre el tamaño de la
imagen original y la comprimida, es decir:
(4.1)
𝐶𝑟 =
𝑛1
𝑛2
Dónde:

𝑛1 representa el tamaño original de la imagen

𝑛2 representa el tamaño de la imagen comprimida
2. Porcentaje de Compresión: Determina el nivel de redundancia de datos en
porcentaje.
% = (𝟏 −
1
) ∗ 𝟏𝟎𝟎
𝐶𝑟
3. Medidas de calidad objetivas33: Se basa en las siguientes métricas:

MSE (Mean Squared Error - Error Medio Cuadrático)

PSNR (Peak Signal-to-Noise Ratio - Relación Señal a Ruido de Pico)

SSIM (Structural Similarity – Índice de Similitud Estructural)
a) MSE: Determina la cantidad de error que existe entre la señal de una
imagen reconstruida respecto a la señal original, es decir mientras más
bajo sea el valor, el error será menor. Se obtiene calculando la diferencia
entre los píxeles de la imagen original y los píxeles de la imagen
reconstruida de acuerdo a la siguiente expresión matemática.
(4.2)
𝑀𝑆𝐸 =
′
2
∑𝑚,𝑛
𝑥,𝑦=0(𝐼(𝑥, 𝑦) − 𝐼 (𝑥, 𝑦))
𝑚𝑥𝑛
Dónde:

𝐼(𝑥, 𝑦) representa los datos de la imagen original en la posición
𝑥, 𝑦

𝐼 ′ (𝑥, 𝑦) representa los datos la imagen reconstruida en la posición
𝑥, 𝑦
33
(Cabezas González, 2012)
43

𝑚 representa la dimensión de ancho de la imagen

𝑛 representa la dimensión de alto de la imagen.
En una imagen RGB, el valor del MSE se calcula por cada plano de
imagen y posteriormente se realiza un promedio de los tres valores.
b) PSNR: Es una medida de estimación de calidad de una imagen, toma en
cuenta la imagen reconstruida y su original. Generalmente este valor
oscila entre 20 y 40 dB (decibelios). Un valor de PSNR alto puede
representar buena calidad aunque no siempre se cumple esta condición.
Esta medida se calcula en base al MSE, de acuerdo a la siguiente
ecuación::
(4.3)
255
𝑃𝑆𝑁𝑅 = 20 log10 (
)
√𝑀𝑆𝐸
c) SSIM: Nace con la intención de crear una medida que se asemeje al
sistema de percepción visual humano, fue creada por Zhou Wang en
2004. Esta medida se calcula solo tomando en cuenta los planos de
luminancia, debido a la poca información estructural contenida en los
planos de diferencia de color. Además, hay que tener en cuenta que este
proceso se lo realiza por bloques de 8x8, y posteriormente se realiza una
media aritmética entre los valores obtenidos en cada bloque. De acuerdo
a la siguiente ecuación:
(4.4)
𝑆𝑆𝐼𝑀(𝑥, 𝑦) =
(2𝜇𝑥 𝜇𝑦 + 𝑐1)(2𝜎𝑥𝑦 + 𝑐2)
(𝜇𝑥2
+ 𝜇𝑦2 + 𝑐1)(𝜎𝑥2 + 𝜎𝑦2 + 𝑐2)
Dónde:

x representa la imagen original

y representa la imagen reconstruida

𝜇𝑥 , 𝜇𝑦 son la media aritmética de x e y respectivamente

𝜎𝑥2 , 𝜎𝑦2 son la varianza de x e y respectivamente.

𝜎𝑥𝑦 es la covarianza entre x e y.

𝑐1 = (0.01𝑥𝑀𝐴𝑋)2 y 𝑐2 = (0.03𝑥𝑀𝐴𝑋)2

𝑀𝐴𝑋, es el valor máximo que puede tomar cada píxel, en este
caso 255.
44
Los valores de SSIM están en el intervalo [0, 1], es decir cuanto más
cercanos estén a 1, habrá menor distorsión estructural entre las dos
imágenes (buena calidad).
PRUEBA 1
Partiendo de los datos anteriormente expuestos, se procedió a seleccionar 10
imágenes por cada formato de imagen, conformado 5 grupos entre los cuales
están:

GRUPO 1. Imágenes a color, formato TIFF

GRUPO 2. Imágenes a color, formato PNG

GRUPO 3. Imágenes a color , formato JPG

GRUPO 4. Imágenes binarias, formato GIF

GRUPO 5. Imágenes escala de grises, formato TIFF
De estos grupos se obtuvieron los siguientes datos:

Nombre de la imagen

Tamaño de la imagen original

Dimensiones: Ancho y Alto

Tamaño de la imagen comprimida

Ratio de compresión

Medias de calidad: MSE, PSNR, SSIM
A continuación se muestra las pruebas que se realizaron en los distintos grupos
de imagen.
GRUPO 1. Imágenes a color, formato TIFF
Figura 4.1 Prueba de imágenes formato TIFF
45
Las pruebas con imágenes de formato TIFF se realizaron en el navegador
Internet Explorer, versión 11.
Tabla 4.1 Resultado de compresión de imágenes TIF
GRUPO 2. Imágenes a color, formato PNG
Figura 4.2 Prueba de imágenes formato PNG
Tabla 4.2 Resultado de compresión de imágenes PNG
46
GRUPO 3. Imágenes a color, formato JPG
Figura 4.3 Resultado de compresión de imágenes JPG
Tabla 4.3 Resultado de compresión de imágenes JPG
GRUPO 4. Imágenes binarias, formato GIF
Figura 4.4 Prueba de imágenes binarias formato GIF
47
Tabla 4.4 Resultado de compresión de imágenes binarias GIF
GRUPO 5. Imágenes a escala de grises, formato TIFF
Figura 4.5 Prueba de imágenes escala de grises formato TIFF
Tabla 4.5 Resultado de compresión de imágenes a escala de gris TIF
Hay que tener en cuenta que las imágenes a prueba presentan dimensiones
inferiores a 1600x1200.
48
En la siguiente tabla se muestran los resultados promedio obtenidos al analizar
cada grupo de imagen.
TIPO_IMG
RATIO_COMPRESIÓN
COMPRESIÓN (%)
MSE
PSNR
SSIM
TIFF
24.23
95.67
106.14
28.42
0.8938
PNG
18.25
94.08
65.76
30.73
0.8803
JPG
5.02
78.46
60.35
31.30
0.8911
GIF
0.31
46.85
62.68
30.94
0.7694
TIFF_GRIS
16.67
92.05
62.36
31.06
0.7637
Tabla 4.6 Medidas de calidad de cada formato de imagen
Utilizando la anterior tabla se realizó gráficos estadísticos que facilitaron la
presentación de los resultados.
1. Ratio de Compresión: En el gráfico se observa que hay una alta
compresión en las imágenes de formato TIFF, seguidas por las de
formato PNG. En imágenes de formato JPG también se puede apreciar
cierto nivel de compresión, a pesar de que es bajo, pero existe
compresión. El inconveniente es en imágenes binarias de formato GIF,
en las que el nivel de compresión no supera el 0.5. Es decir que en este
caso las imágenes aumentaron de tamaño al realizar la compresión. (Ver
Anexo B, Grupo 4.)
RATIO_COMPRESIÓN
30,00
25,00
20,00
15,00
10,00
5,00
0,00
TIFF
PNG
JPG
GIF
TIFF_GRIS
Figura 4.6 Gráfico comparativo del ratio de compresión.
49
2. Porcentaje de Compresión: En el grafico 4.7, se muestra en que las
imágenes de formato TIFF, se alcanza una compresión de 95%, mientras
que en imágenes JPG, se tiene un porcentaje de 78%.
% COMPRESIÓN
120,00
100,00
80,00
60,00
40,00
20,00
0,00
TIFF
PNG
JPG
GIF
TIFF_GRIS
Figura 4.7 Porcentaje de compresión
3. MSE: Se puede apreciar que hay un alto error medio en imágenes a color
de formato TIFF, mientras que en los demás formatos el error medio se
encuentra en el intervalo [62, 65].
MSE
120,00
100,00
80,00
60,00
40,00
20,00
0,00
TIFF
PNG
JPG
Figura 4.8 Error Medio Cuadrático
50
GIF
TIFF_GRIS
4. PNSR: Si bien esta medida no presenta correlación con el sistema visual
humano. Se observa que las imágenes JPG existe alta calidad, los
demás grupos de imágenes se encuentran en el intervalo de [30, 31],
excepto las imágenes a color TIFF, que son las que más baja calidad
presentan.
PSNR
32,00
31,50
31,00
30,50
30,00
29,50
29,00
28,50
28,00
27,50
27,00
26,50
TIFF
PNG
JPG
GIF
TIFF_GRIS
Figura 4.9 Relación señal ruido
5. SSIM: Asumiendo que esta medida se asemeja a la percepción visual
humana, se comprueba que al aplicar la compresión JPEG en imágenes
a color de formato TIFF, PNG y JPG, existe una alta calidad, ya que los
valores obtenidos se asemejan a 0.9. Mientras que en imágenes binarias
GIF y escala de grises TIF los valores oscilan entre 0.75 y 0.77
SSIM
0,9500
0,9000
0,8500
0,8000
0,7500
0,7000
0,6500
TIFF
PNG
JPG
GIF
Figura 4.10 Medida de calidad estructural
51
TIFF_GRIS
Haciendo una síntesis de los resultados obtenidos, se tiene:

Las imágenes que presentan un alto nivel compresión son las imágenes
de formato TIFF por lo tanto su nivel de error medio cuadrático también
es alto, sin embargo tomando en cuenta el valor del SSIM, se verifica que
las imágenes comprimidas tienen una buena calidad.

Las imágenes PNG, presentan alto nivel de compresión, un error medio
bajo y en base a medida de calidad SSIM está cercana a 0.9 es decir
buena calidad.

En imágenes JPG, hay bajo nivel de compresión, bajo error medio y una
calidad buena de acuerdo al SSIM.

En imágenes binarias se aprecia que el ratio de compresión es bastante
bajo debido a que en estas imágenes en vez de disminuir el tamaño del
archivo, tiende a aumentar, y por el mismo hecho el valor de calidad
SSIM está sobre el 0.7.

Por último, en imágenes a escala de grises tienen un alto nivel de
compresión y en cuanto a calidad presentan un valor superior a 0.7.
PRUEBA 2
Esta prueba consiste en comparar el tamaño de compresión de imágenes que se
obtiene en las herramientas: Paint34, Photoshop y la aplicación web desarrollada
(FotoCompressApp). Para esto se generó cinco imágenes en Paint que
contienen figuras geométricas como: rectángulos, círculos, cuadrados, etc,
mismas que son de formato: bmp, tif, gif, png y jpg.
A continuación se muestran las pruebas efectuadas en la aplicación
FotoCompressApp:
34
Paint, es un programa que permite dibujar, colorear, generar y modificar imágenes.
52
IMAGEN BMP
Figura 4.11 Compresión de una imagen de formato BMP
IMAGEN TIF
Figura 4.12 Compresión de una imagen de formato TIFF
53
IMAGEN GIF
Figura 4.13 Compresión de una imagen de formato GIF
IMAGEN PNG
Figura 4.14 Compresión de una imagen de formato PNG
54
IMAGENJPG
Figura 4.15 Compresión de una imagen de formato JPG
En la tabla 4.7 se muestran los resultados obtenidos al efectuar la compresión de
imágenes en tres herramientas.
Tabla 4.7 Compresión de imágenes utilizando diferentes herramientas
TAMAÑO DE COMPRESIÓN
35,00
30,00
25,00
20,00
PAINT
15,00
PHOTOSHOP
10,00
FOTOCOMPRESSAPP
5,00
0,00
bmp
tif
gif
png
jpg
FORMATO DE IMAGEN
Figura 4.16 Comparativo de compresión de imágenes
55
De la tabla 4.7, se tiene que la imagen de formato GIF aumenta el tamaño del
archivo al comprimirla en herramientas como: Paint y Photoshop, mientras que al
utilizar la presente aplicación se reduce el tamaño del archivo de 10.40 KB a
7.20 KB.
La imagen de formato TIFF aumenta el tamaño al comprimir el archivo en las
tres herramientas, sin embargo en la aplicación FotoCompressApp se
incrementa en menor proporción.
En la figura 4.16 se observa que la aplicación que reduce en su mayoría el
tamaño de archivo de imágenes es FotoCompressApp, seguido de Photoshop y
por último Paint.
56
5. CONCLUSIONES

De acuerdo al análisis de las técnicas de compresión, se optó por utilizar
el
algoritmo
de
compresión
JPEG,
ya
que
permite
reducir
significativamente el tamaño de archivos de imágenes, con una pérdida
de calidad mínima. Esto se puede apreciar en los resultados obtenidos en
la métrica de calidad SSIM, donde se tiene valores superiores a 0.7 y
dado que el límite es 1, se considera que hay buena calidad en la
imagen.

El algoritmo de compresión JPEG implementado en la web alcanza altos
niveles de compresión, en imágenes JPG se tiene valores cercanos al
78%, mientras que para otros formatos como TIFF y PNG alcanza un
porcentaje cercano al 90%.

La librería desarrollada permite realizar el proceso de compresión de
imágenes, a través de una aplicación web sencilla y amigable donde el
usuario puede reducir el peso de imágenes de forma interactiva.

La compresión JPEG, no es aplicable para imágenes binarias en formato
GIF, puesto que al comprimir este tipo de imágenes el tamaño del archivo
aumentó; esto se debe a que una imagen binaria solo está compuesta
una matriz de ceros y unos, pero al aplicar el algoritmo JPEG se debe
manejar la imagen en sus tres canales de color, es decir que se aumenta
información y por ende el tamaño del archivo aumenta.

A pesar de que las imágenes en formato JPG ya presentan un nivel de
compresión, también se les puede aplicar
la técnica de compresión
JPEG, haciendo que esta ocupe menos espacio en el disco. El
inconveniente es que cuanto más veces se aplique la compresión, mayor
es la perdida de detalle de la imagen original.

Después de realizar una comparación de la compresión de imágenes
entre Paint, Photoshop y FotoCompressorApp, se concluye que
FotoCompressorApp tiene la ventaja de realizar una mayor reducción en
el peso de imágenes.

JPEG es un algoritmo de compresión simétrico ya que emplea el mismo
tiempo en comprimir y descomprimir una imagen.
57

La compresión de imágenes JPEG mejora velocidad de transmisión de
imágenes debido a la gran reducción en el tamaño de los archivos,
permitiendo de esta forma disminuir el tiempo de transmisión.

El presente proyecto sirve como una guía para dar inicio a nuevas líneas
de investigación en el campo de la compresión de imágenes en áreas
como: la medicina, electrónica, etc.
58
6. RECOMENDACIONES

Se recomienda optimizar la librería de compresión JPEG, de manera que
se reduzca el tiempo de procesamiento de las imágenes subidas y a su
vez se admita imágenes con un tamaño de archivo superior a 1600x1200.

Se recomienda emplear otro algoritmo de compresión para imágenes
binarias.

Para cargar imágenes en formato TIFF, se recomienda utilizar el
navegador Internet Explorer a partir de la versión 10, ya que es el único
navegador que soporta este tipo de formato de imagen.

Debido a la inmensa información digital que se maneja a diario es
recomendable utilizar técnicas de compresión que permitan reducir los
archivos ya sea para almacenarlos o enviarlos a otro medio con el fin de
mejorar la velocidad de transmisión.

La compresión JPEG es bastante útil en medios digitales, ya que reduce
el tiempo de carga de sitios web y redes sociales, pero en medios de
impresión no es muy recomendable hacer uso de esta compresión y en el
caso de hacerlo, solo efectuarlo una vez, debido a que es una técnica de
compresión con pérdida de información y no se garantiza la correcta
visualización de las imágenes sobre el papel una vez impresas.
59
BIBLIOGRAFÍA
1. Alejandro, G. E. (2013). Implementación del Algoritmo RLC (Run Length
Code) para compresión y descompresión aplicado a datos provenientes
de imágenes telemétricas. Escuela Politécnica Nacional, Quito.
2. Barcia, D. (2003). Maestros del Web. Obtenido de
http://www.maestrosdelweb.com/introcss/
3. Barrios, C. E., León, J., & Romero, Y. (2016). METODOLOGÍA DE
PRESSMAN - 2DA PARTE. Obtenido de SistemInformacII:
http://sisteminformacii.wikispaces.com/METODOLOG%C3%8DA+DE+PR
ESSMAN+-+2DA+PARTE
4. Berzal, F., Cortijo, F. J., & Cubero, J. C. (s.f.). Desarrollo Profesional de
Aplicaciones Web con ASP.NET.
5. Besteiro, M., & Rodríguez , M. (s.f.). Recuperado el 05 de abril de 2016,
de http://www.ehu.eus/mrodriguez/archivos/csharppdf/WinForms/GDI.pdf
6. Cabezas González, J. (Septiembre de 2012). Recuperado el 31 de Mayo
de 2016, de
http://oa.upm.es/14048/1/PFC_JAVIER_CABEZAS_GONZALEZ.pdf
7. Carrillo, I. M. (19 de febrero de 2002). Recuperado el 16 de noviembre de
2015, de
http://clusterfie.epn.edu.ec/ibernal/html/CURSOS/OCTUBRE04/CICC200
4/Jpeg.PDF
8. Codedread.com. (s.f.). Codedread.com. Recuperado el 22 de Mayo de
2016, de http://www.codedread.com/scour/
9. Cuevas, E., Zaldivar , D., & Perez, M. (2010). Procesamiento digital de
imágenes con MATLAB y Simulink (Primera ed.). Madrid, España: RAMA.
10. Ecured.cu. (2016). Recuperado el 01 de Mayo de 2016, de
http://www.ecured.cu/C_Sharp
11. Elvex.ugr.es. (01 de Mayo de 2016). Elvex.ugr.es. Obtenido de
http://elvex.ugr.es/decsai/csharp/dotnet/index.xml
12. Es.slideshare.net. (2016). Es.slideshare.net. Recuperado el 02 de Mayo
de 2016, de http://es.slideshare.net/dixzan/tecnologia-microsoft-net
60
13. Esqueda Elizondo, J. J., & Palafox Maestre, L. E. (2005). Fundamentos
para el procesamiento de imágenes. Baja California, México: Universidad
Autónoma de Baja California.
14. Exp3rto. (2014). Exp3rto. Recuperado el 15 de Abril de 2016, de
http://www.exp3rto.com/introduccion-a-html5-capacidades-caracteristicasy-recursos/
15. F, M. (28 de Mayo de 2014). GENBETA. Obtenido de
http://www.genbeta.com/imagen-digital/compressor-io-servicio-decompresion-y-optimizacion-de-imagenes-gratuito-a-fondo
16. Ferreira Escutia, R. (s.f.). Atributos de aplicaciones basadas en WEB.
Obtenido de
http://www.xumarhu.net/isw_1_1_atributos_de_aplicaciones_basadas_en
_web.pdf
17. FileFormat.Info. (Junio de 2015). Recuperado el 16 de Enero de 2016, de
http://www.fileformat.info/mirror/egff/ch09_03.htm
18. Fournier, N., Castro, G., Russo, C., & Bria, O. (s.f.). Recuperado el 23 de
Mayo de 2016, de
http://sedici.unlp.edu.ar/bitstream/handle/10915/23906/Documento_compl
eto.pdf?sequence=1
19. García, N. S. (2006). Aplicación de las TIC a la docencia. Vigo:
Ideaspropias Editorial.
20. GitHub. (s.f.). GitHub. Recuperado el 22 de Mayo de 2016, de
https://github.com/tjko/jpegoptim
21. Gonzalez, R. C., & Woods, R. E. (2002). Digital Image Processing. Upper
Saddle River, New Jersey 07458: Prentice Hall.
22. Google Code . (2016). Google Code . Recuperado el 30 de Enero de
2016, de https://code.google.com/archive/p/jpeg-compressor/
23. Guérin, B.-A. (2014). ASP.NET en C# con Visual Studio 2013 (Vol. 1 st).
Barcelona: Ediciones ENI.
24. Kornel.ski. (s.f.). Kornel.ski. Recuperado el 22 de Mayo de 2016, de
https://kornel.ski/lossygif
25. LIBROSWEB. (s.f.). LIBROSWEB. Recuperado el 25 de Mayo de 2016,
de
http://librosweb.es/libro/fundamentos_jquery/capitulo_7/metodos_ajax_de
_jquery.html
26. Luján Mora, S. (2002). Programación de aplicaciones web: historia,
principios básicos y . San Vicente (Alicante): Club Universitario.
61
27. Mandelbrot, B. (s.f.). La Geometría Fractal de la Naturaleza. Tusquets.
28. Martín, J. (4 de octubre de 2013). CheckApps. Recuperado el 19 de
noviembre de 2015, de http://www.checkapps.net/2013/10/10herramientas-online-optimizar-imagenes-web.html
29. Martín, M. (4 de mayo de 2004). Obtenido de
http://lmi.bwh.harvard.edu/papers/pdfs/2003/martinfernandezCOURSE03c.pdf
30. Martínez Giménez, F., Peris Manguillot, A., & Ródenas Escribá, F. (2004).
Tratamiento de señales digitales mediante wavelets y su uso con Matlab.
Editorial Club Universitario.
31. Menendez, F. J. (2009). Georreferenciación de Cartografia: Datos Raster
y Vectoriales (Vol. Volumen 4 de Cartografia Magazine). EOSGIS SL.
32. Msdn.microsoft. (2016). Msdn.microsoft. Recuperado el 19 de Abril de
2016, de https://msdn.microsoft.com/eses/library/system.drawing.color(v=vs.110).aspx
33. Msdn.microsoft.com. (2016). Recuperado el 19 de Abril de 2016, de
https://msdn.microsoft.com/eses/library/system.drawing.color(v=vs.110).aspx
34. Msdn.microsoft.com. (2016). Msdn.microsoft.com. Recuperado el 30 de
Abril de 2016, de https://msdn.microsoft.com/eses/library/fx6bk1f4(v=vs.100).aspx
35. Nachocabanes.com. (16 de Abril de 2010). Nachocabanes. Recuperado
el 05 de Mayo de 2016, de
http://www.nachocabanes.com/csharp/curso/csharp08b.php
36. Olivé, M. S. (2008). Algoritmo de compresión de imágenes de alta
resolución sin pérdidas. Intituto Politécnico Nacional, México.
37. Optipng.sourceforge.net. (s.f.). Optipng.sourceforge.net. Recuperado el
22 de Mayo de 2016, de http://optipng.sourceforge.net/
38. Owlnet.rice.edu. (2014). Owlnet.rice.edu. Recuperado el 15 de Diciembre
de 2015, de http://www.owlnet.rice.edu/~elec539/Projects99/JAMK/proj1/
39. Pap, F. M. (01 de Abril de 2005). Recuperado el 20 de Mayo de 2016
40. Pngquant.org. (s.f.). Pngquant.org. Recuperado el 22 de Mayo de 2016,
de https://pngquant.org/
41. Quiñónez, J. D. (26 de mayo de 2014). wwwhat´s new. Recuperado el 19
de noviembre de 2015, de http://wwwhatsnew.com/2014/05/26/reducirpeso-imagen-sin-perder-calidad/
62
42. Sánchez Menéndez, F. (2012). Georreferenciación de Cartografia (Vol. 1
st). EOSGIS SL.
43. Scribd. (2016). Obtenido de
https://es.scribd.com/doc/27519905/Servidores-Web
44. Sisternas, M. A. (2014). Aplicación gráfica para la compresión de
información multimedia.
45. SlideShare. (10 de enero de 2011). SlideShare. Obtenido de
http://es.slideshare.net/Amedio/cuantificacin-digital
46. SlideShare. (2016). SlideShare. Recuperado el 23 de Mayo de 2016, de
http://es.slideshare.net/ddocampo/tema2-4360428
47. Vilet, J. R. (2005). Procesamiento digital de Imágenes. Área de
Computación e Informática UASLP.
48. What-when-how. (2016). What-when-how. Recuperado el 22 de Mayo de
2016, de http://what-when-how.com/embedded-image-processing-on-thetms320c6000-dsp/mathematical-preliminaries-image-processing-part-1/
49. Wikipedia. (16 de marzo de 2006). Wikipedia. Recuperado el 02 de abril
de 2016, de
https://es.wikipedia.org/wiki/Joint_Photographic_Experts_Group
50. Wikipedia. (06 de Febrero de 2016). Recuperado el 22 de Marzo de 2016,
de https://es.wikipedia.org/wiki/Transformada_de_coseno_discreta
51. Yañez Durán, C., Pro Concepción, L., & La Serna, N. (s.f.). Recuperado
el 29 de marzo de 2016, de
http://sisbib.unmsm.edu.pe/BibVirtual/publicaciones/risi/2009_n1/v6n1/a0
4v6n1.pdf
52. Zanuy, M. F. (2000). Tratamiento digital de voz e imagen (Vol. 1 st). (M.
B. Editores, Ed.) Barcelona.
63
ANEXOS
ANEXO A
Código fuente
ANEXO B
Manual de usuario
64
ANEXO A
Código Fuente
1. Librería LibImageCompress
CLASE IMAGEN
using
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;
System.Drawing;
System.Drawing.Imaging;
System.IO;
namespace LibImageCompress
{
public class Imagen
{
//ATRIBUTOS
private int ancho;//DIMENSIÓN DEL ANCHO DE LA IMAGEN
private int alto;//DIMENSIÓN DEL ALTO DE LA IMAGEN
private double[,] r, g, b;//COMPONENTES DE LA IMAGEN POR SEPARADO
RED, GREEN, BLUE
//CONSTRUCTOR POR DEFECTO
public Imagen() { }
//CONSTRUCTOR CON PARÁMETROS
public Imagen(Bitmap bitmap)
{
ancho = bitmap.Width;
alto = bitmap.Height;
//inicializar las variables
r = new double[ancho, alto];
g = new double[ancho, alto];
b = new double[ancho, alto];
ObtenerDatos(bitmap);
}
//CONSTRUCTOR2 CON PARÁMETROS
public Imagen(double[, ,] datosImg)
{
ancho = datosImg.GetLength(0);
alto = datosImg.GetLength(1);
r = new double[ancho, alto];
g = new double[ancho, alto];
b = new double[ancho, alto];
for (int i = 0; i < ancho; i++)
{
for (int j = 0; j < alto; j++)
{
r[i, j] = datosImg[i, j, 0];
COMPONENTE DE COLOR ROJO
I
//DATOS DE LA
g[i, j] = datosImg[i, j, 1];
COMPONENTE DE COLOR VERDE
b[i, j] = datosImg[i, j, 2];
COMPONENTE DE COLOR AZUL
//DATOS DE LA
//DATOS DE LA
}
}
//**************************** PROPIEDADES **************//
public double[,] R
{
get { return r; }
set { r = value; }
}
public double[,] G
{
get { return g; }
set { g = value; }
}
public double[,] B
{
get { return b; }
set { b = value; }
}
public int Ancho
{
get { return ancho; }
set { ancho = value; }
}
public int Alto
{
get { return alto; }
set { alto = value; }
}
//**************************** MÉTODOS **********************//
private void ObtenerDatos(Bitmap bm)
{
Color color = new Color();
for (int j = 0; j < bm.Height; j++)
{
for (int i = 0; i < bm.Width; i++)
{
color = bm.GetPixel(i, j);
r[i, j] = color.R; //DATOS DE LA COMPONENTE DE COLOR
ROJO
g[i, j] = color.G; //DATOS DE LA COMPONENTE DE COLOR
VERDE
b[i, j] = color.B; //DATOS DE LA COMPONENTE DE COLOR
AZUL
}
}
}
//MÉTODO QUE PErMITE rECONSTrUIr UNA IMÁgEN A PArTIr DE UNA
MATrIZ DE TrES COMPONENTES DE COLOr
public Bitmap ReconstruirImagen(double[, ,] matImg)
{
Bitmap nuevaIm = new Bitmap(ancho, alto);//CrEA UN bITMAP
AUXILIAr PArA AgrEgAr LOS DATOS
II
Color color = new Color();
int r, g, b;
for (int i = 0; i < ancho; i++)
{
for (int j = 0; j < alto; j++)
{
r = (int)matImg[i, j, 0]; g = (int)matImg[i, j, 1];
b = (int)matImg[i, j, 2];
r = VerificaValor(r); g = VerificaValor(g); b =
VerificaValor(b);
color = Color.FromArgb(r, g, b);
nuevaIm.SetPixel(i, j, color);
}
}
return nuevaIm;
}
//VErIFICA QUE LOS DATOS DE UNA IMAgEN ESTEN EN EL INTErVALO
[0,255]
private int VerificaValor(int dato)
{
int vaux = 0;
if (dato > 255)
vaux = 255;
else if (dato < 0)
vaux = 0;
else
vaux = dato;
return vaux;
}
//CAMBIA EL ESPACIO DE COLOR DE UNA IMAGEN DE RGB AL ESPACIO
YCBCR
public double[, ,] ConvertiRGBaYCBCR()
{
double wr = 0.299, wg = 0.587, wb = 0.114;
double[,] red, green, blue;
//OBTIENE LOS DATOS DE LOS TRES CANALES DE COLOR(ROJO, VERDE
Y AZUL)
red = R; green = G; blue = B;
double[, ,] ycbcr = new double[ancho, alto, 3];//INICIALIZA
LA MATRIZ RESULTANTE
double cal1 = 1 - wb - wr;
double cal2 = 0.5 / (1 - wb);
double cal3 = 0.5 / (1 - wr);
for (int i = 0; i < ancho; i++)
{
for (int j = 0; j < alto; j++)
{
ycbcr[i, j, 0] = wr * red[i, j] + cal1 * green[i, j]
+ wb * blue[i, j];
ycbcr[i, j, 1] = cal2 * (blue[i, j] - ycbcr[i, j, 0])
+ 128;
ycbcr[i, j, 2] = cal3 * (red[i, j] - ycbcr[i, j, 0])
+ 128;
III
}
}
return ycbcr;
}
//CONVIErTE UNA
public double[,
{
double[, ,]
double wr =
double
double
double
double
cal1
cal2
cal3
cal4
IMAgEN EN ESPACIO YCbCr EN EL ESPACIO rgb
,] ConvertirYCBCRaRGB()
rgb = new double[ancho, alto, 3];
0.299, wg = 0.587, wb = 0.114;
=
=
=
=
(1 - wr) / 0.5;
1 - wb;
1 - wb - wr;
1 - wg;
for (int i = 0; i < ancho; i++)
{
for (int j = 0; j < alto; j++)
{
rgb[i, j, 0] = r[i, j] + cal1 * (b[i,
COMPONENETE DE COLOr rOJO
rgb[i, j, 2] = r[i, j] + (cal2 / 0.5)
128); // COMPONENTE DE COLOr AZUL
rgb[i, j, 1] = r[i, j] - (wb * cal2 *
+ wg * cal4 * (b[i, j] - 128)) / (0.5
cal3);//COMPONENTE DE COLOr VErDE
}
}
return rgb;
j] - 128); //
* (g[i, j] (g[i, j] - 128)
*
}
//rESTA 128 A LA MATrIZ DE ESPACIO DE COLOr YCbCr
public double[, ,] Resta()
{
double[, ,] resultado = new double[ancho, alto, 3];
for (int i = 0; i < ancho; i++)
{
for (int j = 0; j < alto; j++)
{
resultado[i, j, 0] = r[i, j] - 128;
resultado[i, j, 1] = g[i, j] - 128;
resultado[i, j, 2] = b[i, j] - 128;
}
}
return resultado;
}
//rEALIZA LA SUMA ENTrE UNA MATrIZ Y UN ESCALAr(128)
public double[, ,] Suma()
{
double[, ,] resultado = new double[ancho, alto, 3];//MATrIZ
rESULTANTE
for (int i = 0; i < ancho; i++)
{
for (int j = 0; j < alto; j++)
{
IV
resultado[i, j, 0] = r[i, j] + 128;
resultado[i, j, 1] = g[i, j] + 128;
resultado[i, j, 2] = b[i, j] + 128;
}
}
return resultado;
}
//COMPLETA CON FILAS Y COLUMNAS A UNA MATrIZ PArA QUE SEA
MULTIPLO DE 8
public double[, ,] CompletarMatriz(double[, ,] matImagen)
{
int f = matImagen.GetLength(0);
int c = matImagen.GetLength(1);
int filas_aum = 0, col_aum = 0;
if (Multiplo8(f)) { filas_aum = 8 - (f % 8); }
if (Multiplo8(c)) { col_aum = 8 - (c % 8); }
double[, ,] nueva = new double[f + filas_aum, c + col_aum,
3];
LLenarMatriz(matImagen, nueva);
nueva = CompletarFilas(matImagen, nueva);
nueva = CompletarColumnas(matImagen, nueva);
return nueva;
}
//VErIFICA SI SE DEbE AgrEgAr FILAS O COLUMNAS A UNA MATrIZ PArA
QUE SEA MULTIPLO DE 8
private int VerificaMultiplo8(int dimension)
{
return dimension % 8;
}
//
private bool Multiplo8(int dimension)
{
if (VerificaMultiplo8(dimension) == 0) { return false; }
return true;
}
//LLENA
private
{
int
int
UNA MATrIZ CON LOS DATOS DE OTrA MATrIZ ANTErIOr
void LLenarMatriz(double[, ,] datos, double[, ,] nueva)
f = datos.GetLength(0);
c = datos.GetLength(1);
for (int i = 0; i <
{
for (int j = 0;
{
nueva[i, j,
nueva[i, j,
nueva[i, j,
}
}
f; i++)
j < c; j++)
0] = datos[i, j, 0];
1] = datos[i, j, 1];
2] = datos[i, j, 2];
}
V
//COMPLETA LAS FILAS DE UNA MATrIZ QUE NO ES DIVIbLE PArA 8
//public int[,] CompletarFilas(int[,] mat, int num_filas)
private double[, ,] CompletarFilas(double[, ,] mat, double[,
,] nueva)
{
int f = mat.GetLength(0);
int fnueva = nueva.GetLength(0);//DIMENSIÓN ANCHO NUEVA
MATrIZ
int cnueva = nueva.GetLength(1);//DIMENSIÓN ALTO NUEVA MATrIZ
//AgrEgA FILAS A UNA MATrIZ PArA QUE EL ANCHO SEA DIVIbLE
PArA 8
for (int i = f; i < fnueva; i++)
{
for (int j = 0; j < cnueva; j++)
{
nueva[i, j, 0] = nueva[f - 1, j, 0];
nueva[i, j, 1] = nueva[f - 1, j, 1];
nueva[i, j, 2] = nueva[f - 1, j, 2];
}
}
return nueva;
}
//COMPLETA LAS COLUMNAS DE UNA MATrIZ QUE NO ES DIVIbLE PArA 8
//public int[,] CompletarColumnas(int[,] mat, int num_col)
private double[, ,] CompletarColumnas(double[, ,] mat,
double[, ,] nueva)
{
int c = mat.GetLength(1);//DIMENSIÓN ALTO MATrIZ
int fnueva = nueva.GetLength(0);//DIMENSIÓN ANCHO NUEVA
MATrIZ
int cnueva = nueva.GetLength(1);//DIMENSIÓN ALTO NUEVA MATrIZ
for (int i = 0; i <
{
for (int j = c;
{
nueva[i, j,
nueva[i, j,
nueva[i, j,
}
}
return nueva;
fnueva; i++)
j < cnueva; j++)
0] = nueva[i, c - 1, 0];
1] = nueva[i, c - 1, 1];
2] = nueva[i, c - 1, 2];
}
}
}
CLASE BLOQUE
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;
System.Drawing;
namespace LibImageCompress
{
VI
public class Bloque
{
//VARIABLES DE LA CLASE
private double[, ,] datos;
//CONSTRUCTOR POR DEFECTO
public Bloque()
{
datos = new double[8, 8, 3];
}
//CONSTRUCTOR CREA UN BLOQUE (MATRIZ 8X8) DADO UNA MATRIZ
public Bloque(double[, ,] bloque8x8)
{
int m = bloque8x8.GetLength(0);
int n = bloque8x8.GetLength(1);
if ((m == 8) && (n == 8))
datos = bloque8x8;
else
Console.Write("Solo se admite matrices de 8x8");
}
//CONSTRUCTOR CON PARÁMETROS
//INGRESA UN VALOR EN LA MATRIZ DE DATOS EN LA POSCIÓN I, J
public Bloque(double r, double g, double b, int i, int j)
{
datos[i, j, 0] = r; datos[i, j, 1] = g; datos[i, j, 2] = b;
}
//PROPIEDADES DE LA CLASE
public double[, ,] Datos
{
get { return datos; }
set { datos = value; }
}
//*********************************MÉTODOS*****************************//
//PERMITE VISUALIZAR LOS DATOS DE LA MATRIZ
public void ImprimeMatriz()
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
Console.Write(Datos[i, j, 0] + " ");
Console.Write(Datos[i, j, 1] + " ");
Console.Write(Datos[i, j, 2] + " ");
}
Console.WriteLine();
}
}
//CALCULA LA TRANSFORMADA DISCRETA DE COSENO EN UN BLOQUE 8X8
public Bloque TDC()
{
double auxR = 0, auxG = 0, auxB = 0;
double Cu, Cv;
const double PI = Math.PI;
const double r = 16;
double val_raiz = 1 / (Math.Sqrt(2));
double[, ,] resultado = new double[8, 8, 3];//MATRIZ
RESULTANTE
for (int u = 0; u < 8; u++)
{
for (int v = 0; v < 8; v++)
VII
{
auxR = 0; auxG = 0; auxB = 0;
if (u ==
Cu =
else
Cu =
if (v ==
Cv =
else
Cv =
0)
val_raiz;
1;
0)
val_raiz;
1;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
auxR += (Math.Cos(((2 * i + 1) * u * PI) / r))
* (Math.Cos(((2 * j + 1) * v * PI) / r)) *
datos[i, j, 0];
auxG += (Math.Cos(((2 * i + 1) * u * PI) /
r)) * (Math.Cos(((2 * j + 1) * v * PI) / r)) *
datos[i, j, 1];
auxB += (Math.Cos(((2 * i + 1) * u * PI) /
r)) * (Math.Cos(((2 * j + 1) * v * PI) / r)) *
datos[i, j, 2];
}
}
auxR *= (1 / Math.Sqrt(r)) * Cu * Cv; auxG *= (1 /
Math.Sqrt(r)) * Cu * Cv; auxB *= (1 / Math.Sqrt(r)) *
Cu * Cv;
resultado[u, v, 0] = auxR; resultado[u, v, 1] = auxG;
resultado[u, v, 2] = auxB;
}
}
Bloque tc = new Bloque(resultado);
return tc;
}
//CALCULA LA TRANSFORMADA INVERSA DE COSENO EN UN BLOQUE 8X8
public Bloque ITDC()
{
double auxR = 0, auxG = 0, auxB = 0;
double Cu, Cv;
const double PI = Math.PI;
const double r = 16;
double val_raiz = 1 / (Math.Sqrt(2));
double[, ,] resultado = new double[8, 8, 3];//MATRIZ
RESULTANTE
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
auxR = 0; auxG = 0; auxB = 0;
for (int u = 0; u < 8; u++)
{
for (int v = 0; v < 8; v++)
{
if (u == 0)
Cu = val_raiz;
else
Cu = 1;
if (v == 0)
Cv = val_raiz;
else
Cv = 1;
VIII
auxR += Cu * Cv * datos[u, v,
(Math.Cos(((2 * i + 1) * u * PI) /
(Math.Cos(((2 * j + 1) * v * PI) / r));
auxG += Cu * Cv * datos[u, v,
(Math.Cos(((2 * i + 1) * u * PI) /
(Math.Cos(((2 * j + 1) * v * PI) / r));
auxB += Cu * Cv * datos[u, v,
(Math.Cos(((2 * i + 1) * u * PI) /
(Math.Cos(((2 * j + 1) * v * PI) / r));
0] *
r)) *
1] *
r)) *
2] *
r)) *
}
}
auxR
*=
(1
/
Math.Sqrt(r));
auxG
*=
(1
/
Math.Sqrt(r)); auxB *= (1 / Math.Sqrt(r));
resultado[i, j, 0] = auxR; resultado[i, j, 1] = auxG;
resultado[i, j, 2] = auxB;
}
}
Bloque tc = new Bloque(resultado);
return tc;
}
//REALIZA EL PROCESO DE CUANTIZACIÓN DE UNA MATRIZ LUEGO DE
APLICAR LA TDC
public Bloque Cuantizar()
{
double[,] quan = new double[8, 8];
double[,] maqlumi = new double[,]{{16,11 ,10, 16, 24, 40, 51,
61},{12, 12, 14, 19, 26, 58, 60, 55},
{14, 13, 16, 24, 40, 57,
69, 56},{14, 17, 22, 29, 51, 87, 80, 52},
{18, 22, 37, 56, 68, 109,
103, 77},{24, 35, 55, 64, 81, 104, 113, 92},
{49, 64, 78, 87, 103,
121, 120, 101},{72, 92, 95, 98, 112, 100, 103, 99}};
double[,] maqcrom = new double[,]{{17, 18, 24, 47, 99, 99,
99, 99},{18, 21, 26, 66, 99, 99, 99, 99},
{24, 26, 56, 99, 99, 99,
99, 99},{47, 66, 99, 99, 99, 99, 99, 99},
{99, 99, 99, 99, 99, 99, 99
,99},{99, 99, 99, 99, 99, 99, 99 ,99},
{99, 99, 99, 99, 99, 99, 99
,99},{99, 99, 99, 99, 99, 99, 99 ,99}};
/*if (tipo == 1) { quan = maqlumi; }
else { quan = maqcrom; }*/
Bloque bloq = new Bloque(Division(datos, maqlumi, maqcrom));
return bloq;
}
//REALIZA EL PROCESO DE INVERSO DE LA CUANTIZACIÓN DE UNA MATRIZ
public Bloque InvCuantizar()
{
double[,] quan = new double[8, 8];
double[,] maqlumi = new double[,]{{16,11 ,10, 16, 24, 40, 51,
61},{12, 12, 14, 19, 26, 58, 60, 55},
{14, 13, 16, 24, 40, 57,
69, 56},{14, 17, 22, 29, 51, 87, 80, 52},
{18, 22, 37, 56, 68, 109,
103, 77},{24, 35, 55, 64, 81, 104, 113, 92},
{49, 64, 78, 87, 103,
121, 120, 101},{72, 92, 95, 98, 112, 100, 103, 99}};
double[,] maqcrom = new double[,]{{17, 18, 24, 47, 99, 99,
99, 99},{18, 21, 26, 66, 99, 99, 99, 99},
{24, 26, 56, 99, 99, 99,
99, 99},{47, 66, 99, 99, 99, 99, 99, 99},
IX
{99, 99, 99, 99, 99, 99, 99
,99},{99, 99, 99, 99, 99, 99, 99 ,99},
{99, 99, 99, 99, 99, 99, 99
,99},{99, 99, 99, 99, 99, 99, 99 ,99}};
Bloque bloq = new Bloque(Producto(datos, maqlumi, maqcrom));
return bloq;
}
public double[,] RecorrerZigZag()
{
int f = 8;//DIMENSIÓN DEL ANCHO DE UNA MATRIZ
int c = 8;//DIMENSIÓN DEL ALTO DE UNA MATRIZ
double[,] vec = new double[f * c, 3];//ALMACENA LOS DATOS DE
UNA MATRIZ EN FORMA DE VECTOR
int pos = -1;//RECORRE LAS POSICIONES DE UN VECTOR
for (int i = 0; i < f * c; i++)
{
for (int j = 0; j < f; j++)
{
for (int k = 0; k < c; k++)
{
if ((j + k) == i)
{
pos++;
if ((i % 2) == 0)
{
vec[pos, 0] = datos[k, i vec[pos, 1] = datos[k, i vec[pos, 2] = datos[k, i }
else
{
vec[pos, 0] = datos[i - k,
vec[pos, 1] = datos[k, i vec[pos, 2] = datos[k, i }
k, 0];
k, 1];
k, 2];
k, 0];
k, 1];
k, 2];
}
}
}
}
return vec;
}
public Bloque InvRecorrerZigZag(double[,] vec)
{
int f = 8;//DIMENSIÓN DEL ANCHO DE UNA MATRIZ
int c = 8;//DIMENSIÓN DEL ALTO DE UNA MATRIZ
int pos = -1;//RECORRE LAS POSICIONES DE UN VECTOR
for (int i = 0; i < f * c; i++)
{
for (int j = 0; j < f; j++)
{
for (int k = 0; k < c; k++)
{
if ((j + k) == i)
{
pos++;
if ((i % 2) == 0)
{
datos[k, i - k, 0] = vec[pos, 0];
datos[k, i - k, 1] = vec[pos, 1];
datos[k, i - k, 2] = vec[pos, 2];
}
X
else
{
datos[i - k, k, 0] = vec[pos, 0];
datos[k, i - k, 1] = vec[pos, 1];
datos[k, i - k, 2] = vec[pos, 2];
}
}
}
}
}
Bloque bloq = new Bloque(datos);
return bloq;
}
//REALIZA LA COMPRESIÓN RLE EN UN BLOQUE
/*
public void CompRLE(double [,] zigzag)
{
int contR = 0, contG = 0, contB = 0;//CUENTA EL NÚMERO DE
CEROS EN SECUENCIA
int dimzz = zigzag.GetLength(0);//DIMENSIÓN DEL VECTOR
List<Point[,]> elementos = new List<Point[,]>();//GUARDA LOS
DATOS EN UNA LISTA
return elementos;
}*/
//REALIZA LA COMPRESIÓN RLE INVERSA
public void InvCompRLE()
{
}
//CALCULA LA DIVISIÓN DE DOS MATRICES COMPONENTE A COMPONENTE
//LAS MATRICES A Y B DEBEN SER DE LA MISMA DIMENSIÓN
public double[, ,] Division(double[, ,] A, double[,]
double[,] C)
{
int f = A.GetLength(0);//DIMENSIÓN DEL ANCHO DE LA MATRIZ
int c = A.GetLength(1);//DIMENSIÓN DEL ALTO DE LA MATRIZ
B,
double[, ,] resultado = new double[f, c, 3];
for (int i = 0; i < f; i++)
{
for (int j = 0; j < c; j++)
{
//resultado[i, j] = Convert.ToInt32(A[i, j] / B[i,
j]);
resultado[i, j, 0] = (int)(A[i, j, 0] / B[i, j]);
resultado[i, j, 1] = (int)(A[i, j, 1] / C[i, j]);
resultado[i, j, 2] = (int)(A[i, j, 2] / C[i, j]);
//resultado[i, j] = A[i, j] / B[i, j];
}
}
return resultado;
}
//CALCULA EL PRODUCTO DE DOS MATRICES COMPONENTE A COMPONENTE
public double[, ,] Producto(double[, ,] A, double[,] B, double[,] C)
{
int f = A.GetLength(0);//DIMENSIÓN DEL ANCHO DE LA MATRIZ
int c = A.GetLength(1);//DIMENSIÓN DEL ALTO DE LA MATRIZ
double[, ,]
RESULTANTE
resultado
=
XI
new
double[f,
c,
3];//MATRIZ
for (int i = 0; i < f; i++)
{
for (int j = 0; j < c; j++)
{
resultado[i, j, 0] = A[i, j, 0] * B[i, j];
resultado[i, j, 1] = A[i, j, 1] * C[i, j];
resultado[i, j, 2] = A[i, j, 2] * C[i, j];
}
}
return resultado;
}
}
}
CLASE MATRIZBLOQUE
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;
namespace LibImageCompress
{
public class MatrizBloque
{
//VARIABLES DE LA CLASE
private Bloque[,] matbloque8x8;
private int m, n;
//CONSTRUCTOR POR DEFECTO
public MatrizBloque() { }
//CONSTRUCTOR CON PARÁMETROS
public MatrizBloque(int m, int n)
{
this.m = m;
this.n = n;
matbloque8x8 = new Bloque[m, n];
}
//CONSTRUCTOR CREA UNA MATRIZ DE BLOQUES CON DATOS DE UNA MATRIZ
GRANDE (DATOS IMAGEN)
public MatrizBloque(double[, ,] matIm)
{
m = matIm.GetLength(0) / 8;
n = matIm.GetLength(1) / 8;
this.matbloque8x8 = new Bloque[m, n];
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
this.matbloque8x8[i, j] = bloque8x8(matIm, i, j);
}
}
}
//CONVIERTE UNA MATRIZ POR BLOQUES EN UNA MATRIZ SIMPLE
public double[, ,] Matriz(MatrizBloque mb)
XII
{
double[, ,] mat_aux = new double[m * 8, n * 8, 3];
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
mat_aux[8 * i + x, 8 * j + y, 0] =
mb.matbloque8x8[i, j].Datos[x, y, 0];
mat_aux[8 * i + x, 8 * j + y, 1] =
mb.matbloque8x8[i, j].Datos[x, y, 1];
mat_aux[8 * i + x, 8 * j + y, 2] =
mb.matbloque8x8[i, j].Datos[x, y, 2];
}
}
}
}
return mat_aux;
}
//*********************************** PROPIEDADES ********************//
public Bloque[,] Matbloque8x8
{
get { return matbloque8x8; }
set { matbloque8x8 = value; }
}
//************************** MÉTODOS *********************************//
//RETORNA UN BLOQUE DE 8X8 DENTRO DE UNA IMAGEN DADAS LAS
COORDENADAS x,y
private Bloque bloque8x8(double[, ,] matI, int x, int y)
{
Bloque submatriz = new Bloque();
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
submatriz.Datos[i, j, 0] = matI[8 * x + i, 8 * y +
j, 0];
submatriz.Datos[i, j, 1] = matI[8 * x + i, 8 * y + j,
1];
submatriz.Datos[i, j, 2] = matI[8 * x + i, 8 * y + j,
2];
}
}
return submatriz;
}
//CALCULA LA TRANSFORMADA DE COSENO EN UNA MATRIZ DE BLOQUES
public MatrizBloque TrasformadaCoseno()
{
MatrizBloque TCD = new MatrizBloque(m, n);
for (int i = 0; i < m; i++)
XIII
{
for (int j = 0; j < n; j++)
{
TCD.Matbloque8x8[i, j] = matbloque8x8[i, j].TDC();
}
}
return TCD;
}
//CALCULA LA TRANSFORMADA INVERSA DE COSENO EN UNA MATRIZ DE BLOQUES
//public MatrizBloque TrasformadaInversaCoseno(MatrizBloque mb)
public MatrizBloque TrasformadaInversaCoseno()
{
MatrizBloque ITCD = new MatrizBloque(m, n);
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
ITCD.Matbloque8x8[i, j] = matbloque8x8[i, j].ITDC();
}
}
return ITCD;
}
//CALCULA LA TRANSFORMADA DE COSENO EN UNA MATRIZ DE BLOQUES
public MatrizBloque Cuantificacion()
{
MatrizBloque QUANT = new MatrizBloque(m, n);
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
QUANT.Matbloque8x8[i, j] = matbloque8x8[i,
j].Cuantizar();
}
}
return QUANT;
}
//CALCULA EL PROCESO INVERSO DE LA CUANTIFICACIÓN EN UNA MATRIZ
DE BLOQUES
public MatrizBloque Descuantificacion()
{
MatrizBloque DESQUANT = new MatrizBloque(m, n);
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
DESQUANT.Matbloque8x8[i, j] = matbloque8x8[i,
j].InvCuantizar();
}
}
return DESQUANT;
}
XIV
//RECORRIDO EN ZIG ZAG MATRIZ DE BLOQUES
public List<double[,]> RecorridoZigzag()
{
List<double[,]> zz = new List<double[,]>();
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
zz.Add(matbloque8x8[i, j].RecorrerZigZag());
}
}
return zz;
}
public MatrizBloque InvRecorridZigZag(List<double[,]> zz)
{
MatrizBloque INV_ZZ = new MatrizBloque(m, n);
int pos = 0;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
INV_ZZ.matbloque8x8[i, j] = matbloque8x8[i,
j].InvRecorrerZigZag(zz[pos]);
pos++;
}
}
return INV_ZZ;
}
//PERMITE VISUALIZAR LOS DATOS DE LOS BLOQUES
public void ImprimeMatbloque()
{
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
matbloque8x8[i, j].ImprimeMatriz();
}
Console.WriteLine();
}
}
}
}
CLASE COMPRESIONJPEG
using
using
using
using
using
using
using
DE UN
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;
System.Drawing;//LIBRERIA PERMITE TRABAJAR CON BITMAPs
System.Diagnostics;//LIBRERIA PARA CALCULAR EL TIEMPO DE EJECUCIÓN
ALGORITMO
namespace LibImageCompress
{
XV
public class CompresionJPEG
{
public Bitmap ImCompress;
public double time;
Imagen img_RGB;
double[, ,] nuevaIMG;
//CONSTRUCTOR POR DEFECTO
public CompresionJPEG() { }
//CONSTRUCTOR CON PARÁMETROS
public CompresionJPEG(Bitmap Imagen)
{
//DETERMINA EL TIEMPO DE EJECUCIÓN DE UN ALGORITMO
Stopwatch tiempo = Stopwatch.StartNew();
img_RGB = new Imagen(Imagen);//DECLARA UN CONSTRUCTOR DE LA
CLASE IMAGEN
double[, ,] img_Compress = CompresionImagen(img_RGB);
//List<double[,]> img_List = CompresionImagen(img_RGB);
//double[, ,] img_Descompress =
DescompresionImagen(img_List);
double[, ,] img_Descompress =
DescompresionImagen(img_Compress);
ImCompress = img_RGB.ReconstruirImagen(img_Descompress);
CodificacionHuffman ch = new CodificacionHuffman();
Point p = new Point(5, -3);
time = tiempo.Elapsed.Seconds;
}
public double[, ,] CompresionImagen(Imagen img)
//public List<double[,]> CompresionImagen(Imagen img)
{
//1. CAMBIAR EL ESPACIO DE COLOR DE LA IMAGEN AL ESPACIO
YCBCR
double[, ,] YCBCR = img.ConvertiRGBaYCBCR();
Imagen img_YCBCR = new Imagen(YCBCR);
//2. RESTAR 128 A CADA PLANO DE IMAGEN
double[, ,] resta_YCBCR = img_YCBCR.Resta();
//COMPLETAR LAS FILAS Y COLUMNAS QUE HAGAN FALTA PARA
//QUE LA MATRIZ SEA MULTIPLO DE 8
nuevaIMG = img_YCBCR.CompletarMatriz(resta_YCBCR);
//3. GENERAR LOS BLOQUES DE 8X8
MatrizBloque calculos = new MatrizBloque(nuevaIMG);
//4. APLICAR LA TRANSFORMADA DE COSENO A CADA BLOQUE
//MatrizBloque calculos1= calculos.TrasformadaCoseno();
calculos = calculos.TrasformadaCoseno();
//5. REALIZAR LA CUANTIFICACIÓN
//MatrizBloque calculos2 = calculos1.Cuantificacion();
calculos = calculos.Cuantificacion();
//List<double[,]> l = calculos.RecorridoZigzag();
double[, ,] imgComprimida = calculos.Matriz(calculos);
XVI
//cr = l[0][0, 0]; cg = l[0][0, 1]; cb = l[0][0, 2];
//dr = nuevaIMG.GetLength(0); dg = nuevaIMG.GetLength(1); db
= resta_YCBCR[0, 0, 2];
return imgComprimida;
//return l;
}
//public double[, ,] DescompresionImagen(List<double[,]>
imgCompress)
public double[, ,] DescompresionImagen(double[, ,] imgCompress)
{
/*MatrizBloque reconstruccion = new
MatrizBloque(nuevaIMG.GetLength(0), nuevaIMG.GetLength(1));
reconstruccion =
reconstruccion.InvRecorridZigZag(imgCompress);*/
MatrizBloque reconstruccion = new MatrizBloque(imgCompress);
reconstruccion = reconstruccion.Descuantificacion();
reconstruccion = reconstruccion.TrasformadaInversaCoseno();
double[, ,] img_nueva =
reconstruccion.Matriz(reconstruccion);
Imagen imagen_aux = new Imagen(img_nueva);
double[, ,] img_YCBCR = imagen_aux.Suma();
Imagen imagen_nueva = new Imagen(img_YCBCR);
double[, ,] img_RGB = imagen_nueva.ConvertirYCBCRaRGB();
return img_RGB;
}
}
}
CLASE CALIDADIMAGEN
using
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;
System.Drawing;
System.Drawing.Imaging;
System.IO;
namespace LibImageCompress
{
public class CalidadImagen
{
private double mse;
private double psnr;
private double ssim;
private float factor_compresion;
//CONSTRUCTOR POR DEFECTO
public CalidadImagen() { }
XVII
//CONTRUCTOR CON PARÁMETROS
public CalidadImagen(Imagen img_original, Imagen img_nueva)
{
mse = Calculo_MSE(img_original, img_nueva);
psnr = Calcula_PSNR(mse);
ssim = SSIM_IMG(img_original, img_nueva);
}
/*************************** PROPIEDADES ***********************/
public double MSE
{
get { return mse; }
set { mse = value; }
}
public double PSNR
{
get { return psnr; }
set { psnr = value; }
}
public double SSIM
{
get { return ssim; }
set { ssim = value; }
}
public float Factor_compresion
{
get { return factor_compresion; }
}
/**************************** MÉTODOS *************************/
//CÁLCULA LA TASA DE COMPRESIÓN ENTRE EL TAMAÑO DE LA IMAGEN
ORIGINAL Y LA IMAGEN COMPRESA
public float Calcula_RatioCompresion(float size_img1, float
size_img2)
{
return (size_img1 / size_img2);
}
//CÁLCULO DEL ERRROR MEDIO CUADRÁTICO
private double Calculo_MSE(Imagen img_original, Imagen img_nueva)
{
int ancho = img_original.Ancho;
int alto = img_original.Alto;
int nump = ancho * alto;
double MSE_R = 0, MSE_G = 0, MSE_B = 0;
for (int i = 0; i < ancho; i++)
{
for (int j = 0; j < alto; j++)
{
MSE_R += Math.Pow(img_original.R[i, j] img_nueva.R[i, j], 2);
MSE_G += Math.Pow(img_original.G[i, j] img_nueva.G[i, j], 2);
MSE_B += Math.Pow(img_original.B[i, j] img_nueva.B[i, j], 2);
}
}
MSE_R /= nump; MSE_G /= nump; MSE_B /= nump;
double MSE_aux = (MSE_R + MSE_G + MSE_B) / 3;
XVIII
MSE = Math.Round(MSE_aux, 2);
return MSE;
}
//CÁLCULO LA MEDIDA DE SEÑAL RUIDO
private double Calcula_PSNR(double MSE)
{
double PSNR_aux = 20 * Math.Log10(255 / (Math.Sqrt(MSE)));
double PSNR = Math.Round(PSNR_aux, 2);
return PSNR;
}
//CALCULA EL SSIM, INDICE DE CALIDAD ESTRUCTURAL
private double SSIM_IMG(Imagen img_original, Imagen img_compress)
{
double[, ,] aux_img1 = img_original.ConvertiRGBaYCBCR();
double[, ,] aux_img2 = img_compress.ConvertiRGBaYCBCR();
int ancho = img_original.Ancho;
int alto = img_original.Alto;
int m, n = 0;
if (ancho % 8 == 0) { m = ancho; }
else { m = ancho - (ancho % 8); }
if (alto % 8 == 0) { n = alto; }
else { n = alto - (alto % 8); }
double[, ,] img1 = new double[m, n, 3];
double[, ,] img2 = new double[m, n, 3];
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
img1[i, j, 0] = aux_img1[i, j, 0];
img1[i, j, 1] = aux_img1[i, j, 1];
img1[i, j, 2] = aux_img1[i, j, 2];
img2[i, j, 0] = aux_img2[i, j, 0];
img2[i, j, 1] = aux_img2[i, j, 1];
img2[i, j, 2] = aux_img2[i, j, 2];
}
}
MatrizBloque mb_img1 = new MatrizBloque(img1);
MatrizBloque mb_img2 = new MatrizBloque(img2);
double aux_ssim = 0;
for (int i = 0; i < m / 8; i++)
{
for (int j = 0; j < n / 8; j++)
{
aux_ssim += Calcula_SSIM(mb_img1.Matbloque8x8[i, j],
mb_img2.Matbloque8x8[i, j]);
}
}
aux_ssim /= (m / 8) * (n / 8);//MEDIA ARITMETICA DE LOS
BLOQUES CALCULADOS
aux_ssim = Math.Round(aux_ssim, 4);
XIX
return aux_ssim;
}
//CALCULA LA MEDIDA DE CALIDAD OBJETIVA
private double Calcula_SSIM(Bloque bloq1, Bloque bloq2)
{
int MAX = 255;
double c1 = Math.Pow(0.01 * MAX, 2);
double c2 = Math.Pow(0.03 * MAX, 2);
double SSIM = 0;
double Ux, Uy = 0;
double Ux2, Uy2 = 0;
double Ox2, Oy2, Oxy = 0;
Ux = Calcula_Media(bloq1); Uy = Calcula_Media(bloq2);
Ux2 = Math.Pow(Ux, 2);
Uy2 = Math.Pow(Uy, 2);
Ox2 = Calcula_Varianza(bloq1, Ux); Oy2 =
Calcula_Varianza(bloq2, Uy);
Oxy = Calcula_Covarianza(bloq1, bloq2, Ux, Uy);
SSIM = ((2 * Ux * Uy + c1) * (2 * Oxy + c2)) / ((Ux2 + Uy2 +
c1) * (Ox2 + Oy2 + c2));
return SSIM;
}
//CALCULA LA MEDIA DE UN BLOQUE DE DATOS
private double Calcula_Media(Bloque bloq)
{
double aux = 0;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
aux += bloq.Datos[i, j, 0];
}
}
aux /= 64;
return aux;
}
//CALCULA LA VARIANDA DE UN BLOQUE DE DATOS
private double Calcula_Varianza(Bloque bloq, double media)
{
double aux = 0;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
aux += Math.Pow(bloq.Datos[i, j, 0] - media, 2);
}
}
aux /= 64;
return aux;
}
//CALCULA LA COVARIANZA DE UN BLOQUDE DE DATOS DADO
XX
private double Calcula_Covarianza(Bloque bloq1, Bloque bloq2,
double media1, double media2)
{
double aux = 0;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
aux += (bloq1.Datos[i, j, 0] - media1) *
(bloq2.Datos[i, j, 0] - media2);
}
}
aux /= 64;
return aux;
}
}
}
2. Aplicación Web
PÁGINA MAESTRA
<%@ Master Language="C#" AutoEventWireup="true"
CodeBehind="Site.master.cs" Inherits="FotoCompressApp.SiteMaster" %>
<!DOCTYPE html>
<html lang="es">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initialscale=1.0" />
<title><%: Page.Title %> - Mi aplicación ASP.NET</title>
<asp:PlaceHolder runat="server">
<%: Scripts.Render("~/bundles/modernizr") %>
</asp:PlaceHolder>
<webopt:bundlereference runat="server" path="~/Content/css" />
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<!-- Estrucutura de la web -->
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
<!-- Tipografía -->
<link href="css/font-awesome.min.css" rel="stylesheet">
<!-- Animación Botones -->
<link href="css/animate.css" rel="stylesheet">
<!-- Estilo Iconos -->
<link href="css/style.css" rel="stylesheet">
<!-- Animación Botones -->
<link href="css/hover.css" rel="stylesheet">
<link href="css/hover-min.css" rel="stylesheet">
<!--***********************************************-->
<link href="css/style_web.css" rel="stylesheet">
<!--Archivo JS para manejar botones de pag Aplicación -->
XXI
<script type="text/javascript" src="js/jquery2.1.1.min.js"></script>
<script type="text/javascript" src="js/app_web.js"></script>
</head>
<body>
<form runat="server">
<asp:ScriptManager runat="server">
<Scripts>
<%--To learn more about bundling scripts in ScriptManager
see http://go.microsoft.com/fwlink/?LinkID=301884 --%>
<%--Framework Scripts--%>
<asp:ScriptReference Name="MsAjaxBundle" />
<asp:ScriptReference Name="jquery" />
<asp:ScriptReference Name="bootstrap" />
<asp:ScriptReference Name="respond" />
<asp:ScriptReference Name="WebForms.js"
Assembly="System.Web"
Path="~/Scripts/WebForms/WebForms.js" />
<asp:ScriptReference Name="WebUIValidation.js"
Assembly="System.Web"
Path="~/Scripts/WebForms/WebUIValidation.js" />
<asp:ScriptReference Name="MenuStandards.js"
Assembly="System.Web"
Path="~/Scripts/WebForms/MenuStandards.js" />
<asp:ScriptReference Name="GridView.js"
Assembly="System.Web"
Path="~/Scripts/WebForms/GridView.js" />
<asp:ScriptReference Name="DetailsView.js"
Assembly="System.Web"
Path="~/Scripts/WebForms/DetailsView.js" />
<asp:ScriptReference Name="TreeView.js"
Assembly="System.Web"
Path="~/Scripts/WebForms/TreeView.js" />
<asp:ScriptReference Name="WebParts.js"
Assembly="System.Web"
Path="~/Scripts/WebForms/WebParts.js" />
<asp:ScriptReference Name="Focus.js"
Assembly="System.Web" Path="~/Scripts/WebForms/Focus.js"
/>
<asp:ScriptReference Name="WebFormsBundle" />
<%--Site Scripts--%>
</Scripts>
</asp:ScriptManager>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container colcontent">
<div class="col-md-4"></div>
<div class="content-header col-md-6">
<a class="hvr-float-shadow" href="Default.aspx"><img
src="IMG_WEB/logotipo.png" /></a>
</div>
</div>
</div>
<div class="container body-content">
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
<!--<hr />-->
</div>
XXII
<div class="sfooter">
<div class="container colfoot">
<footer>
<p>© <%: DateTime.Now.Year %> - Mi aplicación
ASP.NET</p>
</footer>
</div>
</div>
</form>
</body>
</html>
PÁGINA PRINCIPAL
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master"
AutoEventWireup="true" CodeBehind="Default.aspx.cs"
Inherits="FotoCompressApp.Default" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
runat="server">
<div id="content_principal">
<div class="mainbody-section text-center">
<div class="container">
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<!-- Start Carousel Section -->
<div class="home-slider"></div>
<!-- Start Carousel Section -->
<div class="row cont-botones">
<div class="col-md-6">
<div class="menu-item responsive">
<a href="Descripcion.aspx">
<i class="fa fa-home"></i>
<p class="txt_menu">Inicio</p>
</a>
</div>
</div>
<div class="col-md-6">
<div class="menu-item responsive-2">
<a href="Aplicacion.aspx">
<i class="fa fa-file-photo-o"></i>
<p
class="txt_menu">Aplicación</p>
</a>
</div>
</div>
<div class="col-md-6">
<div class="menu-item responsive">
<a href="Documentacion.aspx">
<i class="fa fa-file-text-o"></i>
<p class="txt_menu">Documentación</p>
</a>
</div>
</div>
XXIII
<div class="col-md-6">
<div class="menu-item responsive-2">
<a href="Contacto.aspx">
<i class="fa fa-envelope-o"></i>
<p class="txt_menu">Contacto</p>
</a>
</div>
</div>
</div>
</div>
<div class="col-md-3"> </div>
</div>
</div>
</div>
</div>
</asp:Content>
PÁGINA APLICACIÓN
<%@ Page Title="Aplicación" Language="C#" MasterPageFile="~/Site.Master"
AutoEventWireup="true" CodeBehind="Aplicacion.aspx.cs"
Inherits="FotoCompressApp.Aplicacion" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
runat="server">
<div id="content_principal">
<!--<asp:FileUpload ID="FileUpload1" runat="server" />-->
<h2><%: Title %>.</h2>
<div class="row">
<div class="col-md-6 responsive">
<input id="Upload" type="file" class="upload boton hvrradial-out" accept="image/*" />
<!--<p>Admite formatos de imagen: tiff (Internet
Explorer), jpg, png, bmp, gif </p>-->
</div>
<div class="col-md-6 responsive-2">
<asp:Button ID="btn_descargar" class="boton hvr-sink"
runat="server" Text="DESCARGAR" OnClick="DescargarImagen"
Style="visibility: hidden" />
<input id="btn_comprimir" type="button" value="COMPRIMIR"
class="boton hvr-sink" style="visibility: hidden" />
</div>
</div>
<br />
<div class="row">
<div class=" col-md-6 responsive">
<h4>Imagen Original</h4>
<div id="img_o" class="contenedor_img">
<i id="icono_img" class="fa fa-picture-o icono_style
"></i>
</div>
<div id="info_org" class="info_img">
<p>NOMBRE: <span id="nombre_img"></span></p>
<p>TAMAÑO ORIGINAL: <span
id="tamano_original"></span></p>
<p>
ANCHO: <span id="ancho_img"></span>
</p>
<p>ALTO: <span id="alto_img"></span></p>
</div>
</div>
<div class=" col-md-6 responsive-2">
XXIV
<h4>Imagen Comprimida</h4>
<div id="icompres" class="contenedor_img">
<i id="icono_imgc" class="fa fa-picture-o icono_style
"></i>
</div>
<div id="info_comp" class="info_img">
<p>TAMAÑO COMPRESIÓN: <span
id="tamano_compress"></span></p>
<p>PORCENTAJE COMPRESIÓN: <span
id="porcentaje_comp"></span></p>
<p>ÍNDICE SSIM: <span id="indice_ssim"></span></p>
</div>
</div>
</div>
</div>
</asp:Content>
CONEXIÓN CLIENTE SERVIDOR
$(document).ready(function () {
//ocultar();//OCULTA LOS BOTONES DE DESCARGA
ocultarInfo();//OCULTA EL CUADRO DE LA INFORMACIÓN DE LA IMAGEN
/*---------------------------------------------------------------*/
var datos;//VARIABLE QUE ALMACENA LOS DATOS DE UNA IMAGEN
var file;//VARIABLE QUE LEE EL ARCHIVO DE IMAGEN
var tamano_img;//VARIABLE QUE ALMACENA EL TAMAÑO DE UNA IMAGEN
ORIGINAL
var img_aux, preview;//VARIABLES DE TIPO IMAGEN
var ancho, alto;
/*-------------------------------SELECCIONAR IMAGEN----------------*/
$('#Upload').on('change', function () {
//OCULTA EL BOTÓN DESCARGA SI SE VUELEVE A SELECCIONAR OTRA
IMAGEN
ocultar();//OCULTA LOS BOTONES DE DESCARGA
ocultarInfo();//OCULTA EL CUADRO DE LA INFORMACIÓN DE LA IMAGEN
eliminarImgComprimida();
eliminarImgOriginal();
if (typeof (FileReader) != "undefined") {
//OCULTA EL ICONO PARA CARGAR LA IMAGEN
$("#icono_img").attr("style", "visibility: hidden");
/*-------------------------------------------------------*/
//OBTIENE LA IMAGEN EN LA POSICIÓN 0
file = document.querySelector('input[type=file]').files[0];
preview = new Image();// IMAGEN PARA VISUALIZAR LA IMAGEN QUE
SE CARGA
img_aux = new Image();//IMAGEN AUXILIAR PARA VERIFICAR LA
DIMENSIÓN DE LA IMAGEN
//ASIGNA UN ID A LA IMAGEN
preview.id = "imagen_original";
var reader = new FileReader();
//CARGA LA IMAGEN SELECCIONA
reader.onload = function () {
datos = reader.result;//OBTIENE LA IMAGEN EN CODIFICACIÓN
BASE64
img_aux.src = datos;
img_aux.onload = function () {
if (img_aux.width > 1600 || img_aux.height > 1600) {
alert('Las medidas deben ser: inferiores a 1600x1200,
intente cargar otra imagen.');
}
else {
XXV
/*-------------------------------------------*/
calcula_tamano();
preview.src = datos;//ASIGNA la CADENA BASE64
A LA IMAGEN ORIGINAL
$('i').remove('#icono_img');//OCULTA EL ICONO DE
LA IMAGEN
document.getElementById('img_o').appendChild(prev
iew);
$('#imagen_original').addClass("img_style");
ancho = $('#imagen_original').width();
alto = $('#imagen_original').height();
/*-----------------------------------*/
$("#nombre_img").text(file.name);
//RETORNA LA DIMENSIÓN DEL ANCHO DE UNA IMAGEN
$("#ancho_img").text(preview.naturalWidth +
px");
//RETORNA LA DIMENSIÓN DEL ALTO DE UAN IMAGEN
"
$("#alto_img").text(preview.naturalHeight + "
px");
//RETORNA LA DIMENSIÓN DEL ARCHIVO DE UNA IMAGEN
$("#tamano_original").text(tamano_img + " KB");
mostrarInfoOrginal();//MUESTRA EL CUADRO CON
LA INFORMACIÓN
/*---------------------------------------------*/
$("#btn_comprimir").attr("style", "visibility:
visible");//MUESTRA EL BOTÓN PARA REALIZAR LA
COMPRESIÓN
}
}
}//FIN READER
reader.readAsDataURL($(this)[0].files[0]);
}
});
/*------------------------------------*/
/*--------------------------COMPRIMIR IMAGEN----------------------*/
$('#btn_comprimir').click(function () {
//OCULTA EL ICONO PARA CARGAR LA IMAGEN
$('i').remove('#icono_imgc');
/*-------------------------------------------------------------*/
show_progressbar(); //MUESTRA LA BARRA DE PROGRESO MIENTRAS SE
CARGA LA IMG_COMPRESS
/*-------------------------------------------------------------*/
//ANTES DE SER ENVIADOS LOS DATOS SE RETIRA LOS PRIMEROS
CARACTERES DE LA CADENA BASE64
datos_img
=
datos.replace(/^data:image\/(jpeg|png|bmp|tiff|gif);base64,/, "");
//ARMA UN VECTOR CON LOS DATOS QUE VAN A SER ENVIADOS AL SERVIDOR
var Img = { Image: datos_img, Nombre: file.name };
//REALIZA LA PETICIÓN DE AJAX
//ENVIA DATOS AL SERVIDOR Y DEVUELVE DATOS EN EL CASO DE SER
NECESARIO
/*-------------------------------*/
$.ajax({
url: 'SubirArchivo.ashx',
type: 'POST',
data: Img,
success: function (data) {
//ASIGNA LOS DATOS DE LA IMAGEN COMPRIMIDA
XXVI
var
datos_imgComp
=
'data:image/jpg;base64,'
data.Image_base64;
mostrarImgComprimida(datos_imgComp);
+
//$('img').remove('#barra_cargando');//ELIMINA LA ETIQUETA
DE LA BARRA DE CARGA
eliminarDiv();
/*-----------------------------------------------------*/
$("#tamano_compress").text(data.Size_compress
+
"
KB");//RETORNA EL TAMAÑO DE LA IMAGEN COMPRIMIDA
$("#porcentaje_comp").text(data.Porcentaje
+
"
%");//RETORNA EL PORCENTAJE DE COMPRESIÓN
$("#indice_ssim").text(data.SSim);//RETORNA EL VALOR DE
LA CALIDAD DE UNA IMAGEN
mostrarInfo();//MUESTRA EL CUADRO CON LA INFORMACIÓN DE
LA IMAGEN COMPRIMIDA
mostrar();//MOSTRAR EL BOTÓN DE DESCARGA
alert("LA IMAGEN SE HA COMPRIMIDO EXITOSAMENTE");
/*-----------------------------------------------------*/
},
error: function () { alert("ERROR AL INTENTAR COMPRIMIR LA
IMAGEN") }
});//FIN AJAX
});
/*--------------------------MÉTODOS-----------------------------*/
/**********************************************************************/
//CALCULA EL TAMAÑO DEL ARCHIVO DE UNA IMAGEN
function calcula_tamano() {
tam = file.size;
while (tam >= 1024) {
tam = tam / 1024;
}
tamano_img = tam.toFixed(2);
};
/**********************************************************************/
//MUESTRA UNA IMAGEN CON LA BARRA DE CARGA HASTA QUE SE VISUALICE LA
IMAGEN COMPRIMIDA
function show_progressbar() {
/*
//CREA UNA ETIQUETA IMG
var progress_bar = document.createElement('img');
//ASIGNA UN ID A LA ETIQUETA
progress_bar.id = "barra_cargando";
//RUTA DE LA IMAGEN
progress_bar.src = '../IMG_WEB/progress_bar.gif';
document.getElementById('icompres').appendChild(progress_bar);*/
var div_auxiliar = document.createElement('div');
div_auxiliar.id = "div_aux";
document.getElementById('icompres').appendChild(div_auxiliar);
$('#div_aux').width(ancho);
$('#div_aux').height(alto);
var progress_bar = document.createElement('div');
progress_bar.id = "barra_cargando";
document.getElementById('div_aux').appendChild(progress_bar);
$('#barra_cargando').addClass("cssload-loader");
};
function eliminarDiv() {
$('div').remove('#barra_cargando');
$('div').remove('#div_aux');
};
XXVII
//MOSTRAR LA IMAGEN COMPRIMIDA
function mostrarImgComprimida(base64) {
//CREA UNA ETIQUETA IMG
var img_comp = document.createElement('img');
//ASIGNA UN ID A LA ETIQUETA
img_comp.id = "img_compress";
//RUTA DE LA IMAGEN
img_comp.src = base64;
document.getElementById('icompres').appendChild(img_comp);
$('#img_compress').addClass("img_style");
};
//ELIMINA LA ETIQUETA DE LA IMAGEN COMPRIMIDA
function eliminarImgComprimida() {
$('#img_compress').remove();
};
//ELIMINA LA ETIQUETA PARA MOSTRAR UNA IMAGEN
function eliminarImgOriginal() {
$('#imagen_original').remove();
};
//OCULTA LOS BOTONES PARA DESCARGAR Y COMPRIMIR
function ocultar() {
$("#MainContent_btn_descargar").attr("style",
"visibility:
hidden");
$("#btn_comprimir").attr("style", "visibility: hidden");
};
//OCULTA LOS CUADROS QUE TIENEN LA INFORMACIÓN DE LAS IMÁGENES
function ocultarInfo() {
$("#info_org").css("visibility", "hidden");
$("#info_comp").css("visibility", "hidden");
};
//MUESTRA UN CUADRO CON LA INFORMACIÓN DE LA IMAGEN ORIGINAL
function mostrarInfoOrginal() {
$("#info_org").css("visibility", "visible");
};
//MUESTRA UN CUADRO CON LA INFORMACIÓN DE LA IMAGEN COMPRIMIDA
function mostrarInfo() {
$("#info_comp").css("visibility", "visible");
};
//MUESTRA EL BOTÓN DE DESCARGA Y OCULTA EL BOTÓN PARA COMPRIMIR
function mostrar() {
$("#MainContent_btn_descargar").attr("style",
"visibility:
visible");
$("#btn_comprimir").attr("style", "visibility: hidden");
};
});
XXVIII
ANEXO B
Manual de Usuario
Este documento está diseñado para proporcionar una guía del manejo de cada
una de las opciones de la Aplicación FotoCompressApp.
A continuación se describe cada una de las pantallas a las que puede acceder el
usuario.
1. Pantalla de inicio de la aplicación
La página principal está compuesta por un menú con cuatro opciones: Inicio,
Aplicación, Documentación y Contacto.
2. Dar clic en la opción INICIO. A continuación se visualiza una pantalla, la
cual contiene una breve descripción de la Aplicación.
XXIX
3. Para regresar al menú principal, dar clic en el logotipo fotoCompress.
Regresar al menú
principal
4. La siguiente opción del menú principal es Aplicación.
XXX
Dar clic para escoger
la imagen
5. En esta ventana lo primero que se debe hacer el cargar una imagen. Para
ello dar clic el botón Seleccionar un archivo. En seguida aparece la pantalla
para escoger la imagen que desea comprimir. Esta imagen no debe exceder
las dimensiones de 1600x1200 o 1200x1600.
6. Seleccione la imagen y seguidamente dar clic en abrir como se visualiza en
la siguiente pantalla.
7. La imagen seleccionada aparece en la siguiente pantalla. Además en el lado
superior derecho se muestra un botón que permite realizar la compresión.
XXXI
8. Al dar clic en el botón Comprimir se muestra una barra indicando que se
está cargando la imagen comprimida.
9. Una vez que la imagen se haya cargado completamente, aparece la
siguiente mensaje, indicando que la imagen subida se ha comprimido
exitosamente.
XXXII
10. En caso de que la imagen exceda los límites establecidos anteriormente, se
mostrará el siguiente mensaje de ERROR. De clic en Aceptar, e intente subir
otra imagen con menor dimensión.
11. En la siguiente ventana, al lado derecho se puede visualizar la imagen
comprimida y en la parte superior un botón de descarga, para que pueda
guardar la imagen en el disco de la PC. En la parte inferior se muestran las
características de la imagen y en qué porcentaje se realizó la compresión.
XXXIII
12. Para descargar la imagen comprimida, dar clic en el botón DESCARGAR,
inmediatamente el archivo lo puede visualizar en la parte inferior izquierda de
la ventana.
Imagen
comprimida,
13. En el menú principal,
para revisar
la Documentación acerca del desarrollo
descargada
de la Aplicación se tiene la siguiente opción.
En esta ventana se detallan las clases y componentes más importantes
acerca del desarrollo de la Librería de Compresión y la Aplicación Web.
XXXIV
14. Por último se tiene una página de Contacto, donde constan datos del
desarrollador del presente proyecto.
XXXV
Descargar