Estoy intentando programar un space invaders en ABAP -ya saben el de las navecitas- y bueno... tengo la necesidad de ejecutar eventos que se repitan en un intervalo establecido, y ya que aprendí a usar el timer, decidí poner un ejemplo super sencillo aca.
blablabla blablablabl bnalblablaba
Este programa, escribe "hola" en un report y luego cada 3 segundos escribe "hola otra vez!!"
*&---------------------------------------------------------------------*
*& Autor: Carlos Agreda *
*& Fecha: Feb 29 (Es biciesto) 2008 *
*&---------------------------------------------------------------------*
REPORT ZEJ_TIMER.
data: temporizador type ref to cl_gui_timer.
* Definición del manejador de eventos ------------------------------------
class lcl_event_handler definition.
public section.
class-methods: on_Timer for event finished of cl_gui_timer
importing sender.
endclass.
* Implementación del manejador de eventos ------------------------------
class lcl_event_handler implementation.
method on_Timer.
write: 'Hola otra vez!!'.
sender->run( ).
endmethod.
endclass.
start-of-selection.
create object temporizador.
set handler lcl_event_handler=>on_Timer for temporizador.
temporizador->interval = 3. "el tiempo va en segundos
temporizador->run( ).
write: 'Hola'.
viernes, 29 de febrero de 2008
Timer para ABAP
Publicado por Carlos Agreda en 9:12 9 comentarios
sábado, 16 de febrero de 2008
Esteganografia en Imagenes (LSB)
Es una aplicacion de esteganografia que permite ocultar un texto ascii o inclusive un archivo binario cualquiera dentro de una imagen BMP de 24 bits.
Esteganos: Oculto, Grafia: Escrito
La esteganografía tiene como objeto de estudio las técnicas que permitan ocultar información detrás de otros datos; de tal forma que al ser "mezclados" sean visibles solo los datos de soporte y nuestra información confidencial pase desapercibida ante los ojos de cualquier observador.
Ej.
...si extraemos la primera letra de cada palabra obtenermos:
La iglesia mas antiguaa, puso el rumor ultimo. = Lima peru.
Este es un ejemplo muy sencillo en texto, ya se les podra ocurrir miles de ideas distintas para ocultar sobre texto, pero... como ocultar sobre una imagen?
La primera alternativa para ocultar un mensaje (bits) sobre un BMP de 24 bits es aprovechar su estructura simar al siguiente grafico. solo debemos ocultar nuestros datos justo despues de los metadatos (primeros 54 bytes) y modificar el campo offset (campo que guarda la distancia entre los metadatos y los pixeles) de tal manera que podamos hacer espacio para todo lo que queremos esconder.
Esta alternativa si bien es cierto es muy sencilla de implementar tiene el defecto de que la imagen obtenida sera considerablemente grande, seria extranho tener una imagen de un icono (10x10) que nos ocupe 10 Mb no?
Otra alternativa -desde mi parecer mucho mejor- es esconder lo que queremos esconder en los LSB de cada componente de un pixel.
En espanhol:
Cada pixel, en un archivo BMP (de 24 bits), esta representado por 3 bytes conteniendo la intensidad de color para ROJO, VERDE y AZUL (RGB: red, green, blue). Entonces combinando valores en esas posiciones podemos obtener los = (16777216) colores que puede mostrar un pixel, habitualmente se dice 16 millones de colores, pero son un poquito mas.
Bueno entonces... cada byte contiene un valor entre 0 y 255 (en binario 00000000 y 11111111), estos bytes igual que en el sistema decimal conforme sus cifras esten mas a la izquierda tendran mas valor (peso) por citar un ejemplo:
5768, si cambiamos la primera cifra (la mas significativa) a 3 nos queda 3768, la diferencia es notable. Pero si cambiamos la ultima cifra (la menos significativa) por ejemplo a un 2 nos queda 5762, la diferencia es relativamente minima.
Con esto quiero decir que podemos modificar los LSB (less significant bits, o cifras menos significativas) sin producir mayor alteracion.
Un caso:
Si observamos estos dos pixels, tan solo se le ha cambiado una unidad a cada componente R, G, B, y la variacion de color ha sido minima. Al ojo humano son practicamente el mismo color.
Con esto hemos logrado sembrar 3 bits que originalmente eran 101 ahora hemos sembrado 010, eso significa que por cada pixel podemos almacenar 3 bit sin producir un cambio aparente en el pixel.
Si repetimos este paso, recorriendo los pixels de la imagen, podemos ir sembrando (ocultando) los bits que querramos dentro de nuetra imagen. En cada pixel podremos poner 3 bits es decir necesitaremos masomenos 8 pixels para poner 3 bytes (un byte tiene 8 bits :P).Como se puede ver no es muy dificil
Esta es una imagen que contiene un mensaje, si logran recuperarlo lo comentan :P
La imagen de bart con el mensaje la pueden descargar aqui.
La aplicacion ejecutable la pueden descargar aqui.
El codigo fuente para vb 6, lo pueden descargar aqui.
Un instalador de la aplicacion lo pueden descargar de aqui.
y si no tienen el winrar lo pueden descargar de aqui
Saludos.
Publicado por Carlos Agreda en 2:52 32 comentarios
Etiquetas: Computer Science, Tratamiento Imagenes
viernes, 15 de febrero de 2008
SAP Consultant Certification
Navegando por ahi me tope con los contenidos para la certificación ABAP. Me pareció util postearlo por aca.
Courses for certification preparation: TAW10 (ABAP Workbench Fundamentals); TAW12 (ABAP Workbench Concepts)
Please note that you are not allowed to use any reference materials during the certification test (no access to online documentation or to any SAP system).
The certification test Development Consultant SAP NetWeaver 2004– Application Development Focus ABAP verifies the knowledge in the area of the SAP NetWeaver for the consultant profile Application Development Focus ABAP. This certificate proves that the candidate has a basic understanding within this consultant profile, and can implement this knowledge practically in projects.
The certification test consists of questions from the areas specified below:
Topic Areas
2. ABAP Workbench Basics (++)
Data types and data objects (declaration)
Internal tables
Data retrieval (authorization check)
Subroutines
Function groups and function modules
Program calls and memory management
3. Advanced ABAP (++)
ABAP runtime
Data types and data objects (usage)
Open SQL (high-performance programming)
Dynamic programming
4. ABAP Objects (++)
Classes and objects
Inheritance
Polymorphism (casting)
Interfaces
Events
Global classes and interfaces
Exception handling
Shared objects
5. ABAP Dictionary (++)
Database tables
Performance for table accesses
Consistency by means of input check (foreign key dependency)
Dependency for ABAP Dictionary objects
Views
Search helps
6. List Creation Techniques (++)
Data output in lists
Selection screen
Logical database
Interactive lists
List creation with the ALV grid control:
- Simple lists
- Field catalog
- Layout
- Event handling
7. Dialog Programming (++)
Screen (basics)
Program interface (GUI title, GUI status)
Screen elements for output (text fields, status icons, and group boxes)
Screen elements for input/output
Subscreen and tabstrip control
Table control
Context menu
Lists in dialog programming
8. Database Changes (+)
Database updates with open SQL
LUWs and client/server architecture
SAP locking concept
Organize database changes
Complex LUW processing
Number assignment
Change document creation
9. Enhancements and Modifications (+)
Changes to the standard SAP system
Personalization
Enhancements to ABAP Dictionary elements
Enhancements via customer exits
Business Transaction Events
Business Add-Ins
Modifications
Amount of questions by topic (as percentage of test):
+ = 1 - 10%
++ = 11 - 20%
+++ = over 20%
No responsibility is taken for the correctness of this information. Copyright © SAP AG 2005.
Fuente: https://websmp108.sap-ag.de/~sapidp/011000358700006455222004E
Publicado por Carlos Agreda en 12:21 7 comentarios
Etiquetas: ABAP, Certificacion SAP-ABAP, SAP
Certificación SAP-ABAP
Imagino que muchos como yo quisieran certificarse algún día en SAP ABAP -mundillo interesante en el que he venido a llegar de casualidad- y dado que estoy al inicio de esta aventura de recopilar información y empezar a estudiar, me he decidido postear cada paso que voy dando hasta llegar a lograrlo (espero :P).
Síganme los buenos!!!
Todo material es bienvenido, los comentarios y recomendaciones, también.
Saludos.
Publicado por Carlos Agreda en 11:57 2 comentarios
Etiquetas: ABAP, Certificacion SAP-ABAP, SAP
jueves, 14 de febrero de 2008
SAP CRM para iPhone
SAP está trabajando en un CRM -Customer Relationship Management- móvil para iPhone. El argumento de SAP es que sus clientes corporativos prefieren iPhone antes que otras marcas y no pueden perder el pulso del mercado. SAP, líder de software de gestión e inteligencia empresarial ha decidido desarrollar aplicaciones para iPhone comenzando con CRM 2007.
El nuevo CRM, que se empezará a comercializar a finales de mes, contará con un programa que permitirá el envío de datos de clientes a los teléfonos iPhone de Apple. SAP ha buscado en esta nueva generación de aplicaciones utilizar todas las experiencias de los servicios de la web 2.0, inspirándose en las herramientas de Google y Yahoo.
El CRM móvil será un instrumento imprescindible para que las empresas puedan brindar mayor satisfacción de los clientes, mejorar sus objetivos de rendimiento financiero e impulsar su ventaja competitiva en el mercado, comenzando por los equipos de fuerza de ventas para llegar, tarde o temprano, a las actividades de aprovisionamiento y producción.
Publicado por Carlos Agreda en 19:48
Etiquetas: Noticias GeeK, SAP
Mujer afgana identificada por su iris
Sharbat Gula, fotografiada en 1984 a los 12 años en un refugio en Pakistán por el fotógrafo de la National Geographic Steve McCurry, y localizada 18 años después en una remota parte de Afganistán donde fue nuevamente fotografiada por McCurry, es mencionada por la National Geographic en su revista y en su website.
John Daugman todo un ícono en el procesamiento y reconocimiento del iris humano, calculó el IrisCode de ambos ojos en la fotografía de 1984. Un sección procesada de la fotografía de 1984 se muestra aquí. La circunferencia muestra la automática localización del iris y sus bordes, el descarte de ciertas reflexiones especulares del ojo y la representación del IrisCode. Luego calculó el IrisCods de ambos ojos fotografiados en 2002. La imágenes procesadas pueden ser vistas aquí, para el ojo izquierdo y derecho.
Aún lo más interesante surge a continuación. Cuando se obtuvo la distancia de Hamming de los ojos izquierdo y derecho(los cuales en todo humano son completamente diferentes), se obtuvo medidas muy similares, que como el mismo Daugman manifiesta es estadísticamente casi imposible para diferentes iris se muestren medidas tan poco distintas. La estadística matemática de que tal evento pase es de seis millones a uno para el ojo derecho y 10 elevado a 15 para el ojo izquierdo. NatGeo aceptó nuevamente publicar esta conclusión.
Como se ve el IrisCode tuvo todo un reto, y salió con algunas heridas pero victorioso al fin.
Fuente: http://www.seccperu.org/?q=node/608
Publicado por Carlos Agreda en 18:17 26 comentarios
Etiquetas: Biometria, Computación Grafica, Computer Science, Inteligencia Artificial, Noticias GeeK, Tratamiento Imagenes
Algo sobre lógica difusa.
Han podido ver sus lavadoras u otros electrodomésticos que dicen "FUZZY LOGIC?"
Habitualmente las premisas de la lógica que conocemos tienen sólo dos extremos: o son completamente ciertas o son totalmente falsas (1 v 0). En el mundo de la lógica difusa las premisas pueden tener un grado de certeza que le permite acercar la matemática al lenguaje impreciso del hombre común, ya que está repleto de términos vagos como “poco”, “mucho”, “tibio”, etc.
Entonces podemos decir que la lógica difusa analiza los métodos y principios del razonamiento a partir de proposiciones IMPRECISAS similar a como lo haría un ser humano: "Si hace algo de frio y tengo muchas cosas que hacer entonces no salgo", ¿Cuánto es algo o mucho?
De esa manera tu lavadora puede decirdir cuanto tiempo lavar, cuanto detergente pedir, y cuanta agua cargar, con reglas de inferencias del tipo:
Si la ropa esta muy sucia, y el agua es fria, y ademas hay mucha ropa -> cargar mucha agua y lavar durante mucho tiempo. :P
Para los q quieren saber mas...
Un sistema difuso convencional consta de 3 etapas que son las siguientes:
Fuzzyficación
Consiste en llevar los valores del mundo real al ambiente Fuzzy mediante el uso de funciones de membresía. Por ejemplo, si tenemos un paciente con fiebre, podemos plantear un modelo en el que la situación de fiebre no se restringe sólo a dos valores (hay fiebre o no hay fiebre), sino que tenemos todo un rango de temperaturas posible, asi un paciente que tiene 38C de tempratura puede tener fiebre como no tenerla pero en cierto grado.
Inferencia Lógica
Para poder operar con los Conjuntos Difusos es necesario definir las operaciones elementales entre ellos. Esto implica definir el modo de calcular las funciones de pertenencia a estos tres conjuntos.
Siento FP una función que nos devuelve el grado de pertenencia al un conjunto difuso, Zadeh propone:
FP(X AND Y) = mínimo de (FP (X), FP(Y))
FP (X OR Y) = máximo de (FP (X), FP (Y))
NOT FP = 1 – FP (X), considerando pertenencia total = 1
En realidad, estas expresiones son bastante arbitrarias y podrían haberse definido de muchas otras maneras. En la actualidad se considera correcto definir el operador AND mediante cualquier aplicación t-norma y el operador OR mediante cualquier aplicación s-norma.
Defuzzyficación
Después de calcular las reglas fuzzy y evaluar las variables fuzzy, necesitaremos trasladar estos valores nuevamente hacia el mundo real. El método más popular de defusificación es el cálculo del centro de gravedad ó centroide, el cual retorna el centro del área bajo la curva de la inferencia.
El término difuso aplicado a la lógica procede de la expresión fuzzy sets (conjuntos difusos) acuñada por Lofti A. Zadeh. Zadeh prefirió el término fuzzy para denominar a sus conjuntos y a la lógica en la que se apoya su análisis. Uno de los países donde más éxito han tenido los sistemas difusos ha sido en Japón. Empresas como Fuji Elec.& TIT han desarrollado aplicaciones de control fuzzy para el proceso de purificación del agua, Hitachi con una aplicación de control fuzzy para el Metro en Sendai City o Matsushita con una aplicación de control fuzzy para la unidad de suministro de agua caliente para uso doméstico. Merece una mención especial la creación de LIFE (Laboratory for International Fuzzy Engineering Research) en marzo de 1989, creado por el Ministerio de Comercio Internacional e Industria en Japón (MITI). Pero también en USA las empresas han comenzado a aplicar la lógica difusa a sus desarrollos y proyectos. Entre otras encontramos a la NASA, Boeing, Rochwell, Bell o a Ford Motor Co., que experimenta con un sistema de aparcamiento automático para camiones con remolque.
Los comentarios son bienvenidos.
Publicado por Carlos Agreda en 9:15 12 comentarios
Etiquetas: Computer Science, Inteligencia Artificial
jueves, 7 de febrero de 2008
Plantilla super básica para aprender ALV
Esta es una plantilla que hice hace un tiempo cuando aprendí a usar ALV, es la plantilla más básica como ejemplo para aprender, luego uno ya puede ir agregándole otras capacidades que ALV permite.
Solo cambia lo que está en rojo y para obtener un programa que muestra un ALV.
*&---------------------------------------------------------------------*
*& autor....... : Carlos Agreda*
*& Descripción..: programa plantilla basico para alv *
*&---------------------------------------------------------------------*
REPORT ZEJ_ALV.
type-pools: slis.
Data: gt_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.
Data: BEGIN OF it_datos OCCURS 0.
INCLUDE STRUCTURE tabla_diccionario.
Data: END OF it_datos .
perform llenaDatos.
perform llenaFieldcat.
perform mostrarALV.
*llena la tabla interna con los datos que queremos mostrar
form llenaDatos.
SELECT * FROM tabla_diccionario INTO TABLE it_datos.
endform.
*Llena el fieldcat para cada campo
form llenaFieldcat.
* repetir este bloque por cada campo
CLEAR gt_fieldcat.
gt_fieldcat-SELTEXT_L = 'caption_campo'.
gt_fieldcat-fieldname = 'nombre_del_Campo'.
gt_fieldcat-tabname = 'tabla_diccionario'.
APPEND gt_fieldcat.
*fin del bloque
endform.
* muestra el alv
form mostrarALV.
CALL FUNCTION 'REUSE_ALV_LIST_DISPLAY'
EXPORTING
it_fieldcat = gt_fieldcat[]
TABLES
t_outtab = it_datos
EXCEPTIONS
program_error = 1
OTHERS = 2.
endform.
Espero no haber olvidado nada.
Publicado por Carlos Agreda en 6:35 1 comentarios
Etiquetas: ABAP
miércoles, 6 de febrero de 2008
Tres en raya para ABAP
Ésta es una implementacion -ociosa- del juego de 3 en raya en ABAP/4, por el momento es muy torpe -juega totalmente aleatorio- y poco robusta, pero es un buen ejemplo de programas interactivos.
El código está listo para pegar poner F8 y jugar.
Prometo implementar la heurística del juego para que no le puedas ganarle, pero eso será en otro post.
Por cierto el generador de aleatorios de ABAP es muy malo, prometo implementar uno y postearlo también.
*&---------------------------------------------------------------------*
*& Autor.........: Carlos Agreda Pérez
*& Descripción...: Juego de 3 en raya
*& Fecha ........: 06/FEB/2008 *
*&---------------------------------------------------------------------*
REPORT ZTMP_3R no standard page heading.
Data: aleatorio type i, posX type i, posY type i.
Data: ganoMaquina type i value 0.
Data: ganoJugador type i value 0.
Data: Begin of estado,
P1 VALUE '-', P2 VALUE '-', P3 VALUE '-', P4 VALUE '-', P5 VALUE '-',
P6 VALUE '-', P7 VALUE '-', P8 VALUE '-', P9 VALUE '-',
End of estado.
perform elegirAccionMaquina.
perform mostrarEstado.
* CAPTURA DE LA JUGADA-----------------------
AT LINE-SELECTION.
GET CURSOR LINE posY OFFSET posX.
if posX = 10 and posY = 4. estado-P1 = 'o'. endif.
if posX = 20 and posY = 4. estado-P2 = 'o'. endif.
if posX = 30 and posY = 4. estado-P3 = 'o'. endif.
if posX = 10 and posY = 6. estado-P4 = 'o'. endif.
if posX = 20 and posY = 6. estado-P5 = 'o'. endif.
if posX = 30 and posY = 6. estado-P6 = 'o'. endif.
if posX = 10 and posY = 8. estado-P7 = 'o'. endif.
if posX = 20 and posY = 8. estado-P8 = 'o'. endif.
if posX = 30 and posY = 8. estado-P9 = 'o'. endif.
perform verificarGanador.
if ganoJugador NE 1.
perform elegirAccionMaquina.
endif.
perform mostrarEstado.
* SUBPROGRAMAS ------------------------------------
form elegirAccionMaquina.
perform generarAleatorioLibre.
if aleatorio = 1. estado-P1 = 'X'. endif.
if aleatorio = 2. estado-P2 = 'X'. endif.
if aleatorio = 3. estado-P3 = 'X'. endif.
if aleatorio = 4. estado-P4 = 'X'. endif.
if aleatorio = 5. estado-P5 = 'X'. endif.
if aleatorio = 6. estado-P6 = 'X'. endif.
if aleatorio = 7. estado-P7 = 'X'. endif.
if aleatorio = 8. estado-P8 = 'X'. endif.
if aleatorio = 9. estado-P9 = 'X'. endif.
endform.
form mostrarEstado.
write: /, /, /.
write at 11(1): estado-P1. write at 21(1): estado-P2. write at 31(1): estado-P3. write: /.
write at 11(1): estado-P4. write at 21(1): estado-P5. write at 31(1): estado-P6. write: /.
write at 11(1): estado-P7. write at 21(1): estado-P8. write at 31(1): estado-P9.
endform.
form generarAleatorioLibre.
CALL FUNCTION 'QF05_RANDOM_INTEGER'
EXPORTING
RAN_INT_MIN = 1
RAN_INT_MAX = 9
IMPORTING
RAN_INT = aleatorio
EXCEPTIONS
OTHERS = 1.
if aleatorio = 1 and estado-P1 NE '-'. perform generarAleatorioLibre. endif.
if aleatorio = 2 and estado-P2 NE '-'. perform generarAleatorioLibre. endif.
if aleatorio = 3 and estado-P3 NE '-'. perform generarAleatorioLibre. endif.
if aleatorio = 4 and estado-P4 NE '-'. perform generarAleatorioLibre. endif.
if aleatorio = 5 and estado-P5 NE '-'. perform generarAleatorioLibre. endif.
if aleatorio = 6 and estado-P6 NE '-'. perform generarAleatorioLibre. endif.
if aleatorio = 7 and estado-P7 NE '-'. perform generarAleatorioLibre. endif.
if aleatorio = 8 and estado-P8 NE '-'. perform generarAleatorioLibre. endif.
if aleatorio = 9 and estado-P9 NE '-'. perform generarAleatorioLibre. endif.
endform.
form verificarGanador.
if estado-P1 = 'X' and estado-P2 = 'X' and estado-P3 = 'X'. ganoMaquina = 1. endif.
if estado-P4 = 'X' and estado-P5 = 'X' and estado-P6 = 'X'. ganoMaquina = 1. endif.
if estado-P7 = 'X' and estado-P8 = 'X' and estado-P9 = 'X'. ganoMaquina = 1. endif.
if estado-P1 = 'X' and estado-P4 = 'X' and estado-P7 = 'X'. ganoMaquina = 1. endif.
if estado-P2 = 'X' and estado-P5 = 'X' and estado-P8 = 'X'. ganoMaquina = 1. endif.
if estado-P3 = 'X' and estado-P6 = 'X' and estado-P9 = 'X'. ganoMaquina = 1. endif.
if estado-P3 = 'X' and estado-P5 = 'X' and estado-P7 = 'X'. ganoMaquina = 1. endif.
if estado-P1 = 'X' and estado-P5 = 'X' and estado-P9 = 'X'. ganoMaquina = 1. endif.
if estado-P1 = 'o' and estado-P2 = 'o' and estado-P3 = 'o'. ganoJugador = 1. endif.
if estado-P4 = 'o' and estado-P5 = 'o' and estado-P6 = 'o'. ganoJugador = 1. endif.
if estado-P7 = 'o' and estado-P8 = 'o' and estado-P9 = 'o'. ganoJugador = 1. endif.
if estado-P1 = 'o' and estado-P4 = 'o' and estado-P7 = 'o'. ganoJugador = 1. endif.
if estado-P2 = 'o' and estado-P5 = 'o' and estado-P8 = 'o'. ganoJugador = 1. endif.
if estado-P3 = 'o' and estado-P6 = 'o' and estado-P9 = 'o'. ganoJugador = 1. endif.
if estado-P3 = 'o' and estado-P5 = 'o' and estado-P7 = 'o'. ganoJugador = 1. endif.
if estado-P1 = 'o' and estado-P5 = 'o' and estado-P9 = 'o'. ganoJugador = 1. endif.
if ganoMaquina = 1. Write 'Te gané'.
elseif ganoJugador = 1. Write 'Ganaste'.
endif.
endform.
Publicado por Carlos Agreda en 15:57 1 comentarios
Etiquetas: ABAP, Inteligencia Artificial, Juegos
Capturar la posición de un doble clic en un Report ABAP/4
Estuve implementando un tres en raya en ABAP -para refrescar ABAP y aprovechando que no hay proyectos- y para recibir las jugadas me fue necesario capturar la posición de un doble clic sobre el report.
Es bien fácil tan solo utilizar el evento AT LINE-SELECTION. (se invoca cuando das el doble clic) y la instrucción GET CURSOR LINE posY OFFSET posX.
Aqui un ejemplo sencillo:
*& Autor.........: Carlos Agreda
*& Descripción...: Captura la posición del doble
*& clic y la escribe en pantalla
*& Fecha ........: 06/FEB/2008
REPORT ZEJEMPLO.
DATA : posX type i, posY type i.
write 'hola'.
AT LINE-SELECTION.
GET CURSOR LINE posY OFFSET posX.
write: posX, posY.
La restricción es que nomás se podrán dar clics sobre la superficie escrita, en éste caso solo se podrá dar doble clic sobre "hola".
Prometo postear el fuente del tres en raya ni bien lo termine :P
Publicado por Carlos Agreda en 12:23 0 comentarios
Etiquetas: ABAP
Destripando un BMP (24 bits)
Existe una gran variedad de formatos de imágenes tal como BMP, TIFF, GIF, PNG, JPEG, etc. El más sencillo de todos es el formato BMP de 24 bits.
Características:
No es comprimido (Una desventaja con respecto a espacio pero ventaja por su simplicidad)
Por no ser comprimido es de alta calidad
Se puede ver en cualquier visor de imágenes por ser el mas básico.
Veamos que hay dentro...
Los Primeros 54 Bytes contienen los metadatos de nuestra imagen y su estructura es la siguiente:
2 bytes - contienen siempre 'BM', para poder identificar que es un bmp
4 bytes - tamaño del archivo (en bytes)
4 bytes - Reservados, contienen ceros (reservados para usos futuros)
4 bytes - offset, distancia entre cabecera y píxels (no lo usaremos)
4 bytes - Tamaño de Metadatos (tamaño de esta estructura = 40)
4 bytes - Ancho (numero de píxeles horizontales)
4 bytes - Alto (numero de pixeles verticales)
2 bytes - Numero de planos de color (No lo usaremos, valdrá 1)
2 bytes - Profundidad de color (debe ser 24 para nuestro caso)
4 bytes - Tipo de compresión (valdrá 0, ya que es descomprimido)
4 bytes - Tamaño de la estructura Imagen
4 bytes - Píxeles por metro horizontal (No lo usaremos)
4 bytes - Píxeles por metro vertical (No lo usaremos)
4 bytes - Cantidad de colores usados (No lo usaremos)
4 bytes - Cantidad de colores importantes (Tampoco usaremos)
Suman 54 bytes, y son los primeros 54 bytes que debemos leer de nuestro archivo.
Podemos leerlo uno a uno pero lo mejor es crear una estructura y leerlos todo de un solo paso.
Ejemplo de Estuctura para Visual Basic:
Public Type tipoMetadatosBMP
B As Byte
M As Byte
tamaño As Long
reservado As Long
offset As Long
tamañoMetadatosB
ancho As Long
alto As Long
planos As Integer
profundidadColor As Integer
tipoCompresion As Long
tamañoEstructuraImagen As Long
pixelsPorMetroH As Long
pixelsPorMetroV As Long
cantidadColoresUsados As Long
cantidadColoresImportantes As Long
End Type
Ejemplo de estructura para C++:
struct tipoMetadatosBMP
{ char bm[2];
int tamano;
int reservado;
int offset;
int tamanoMetadatos;
int alto;
int ancho;
short numeroPlanos;
short profundidadColor;
int tipoCompresion;
int tamanoEstructura;
int pxmh;
int pxmv;
int coloresUsados;
int coloresImportantes;
} ;
No debe variar mucho de lenguaje en lenguaje.
Inmediatamente después de Nuestra cabecera (metadatos), vienen los píxeles (si, esos cuadraditos de colores que conforman nuestra imagen)
Cada Píxel se almacena en 24 bits (3 bytes)
De los 24 bits = 3 bytes, se utilizan 1 byte por cada color básico es decir...
Un byte parta R, Un byte para G, Un byte para B
NO, no son los colores rastas :P, son los colores básicos para el BMP, cada color puede ser obtenido mediante una combinacion de R (red), G (green) y B (blue).
Considerando que un byte puede almacenar 256 valores diferentes, tenemos:
256 (R) x 256 (G) x 256 colores (B) = 16777216 Colores RGB
Por alguna razón que desconozco al momento de diseñar el formato los ordenaron BGR y no RGB es decir primero el byte para azul, luego el byte para verde y luego el byte para verde.Importante!!! :
Ahora ya que al leer los metadatos obtuvimos la resolución (Sí, la RESOLUCIÓN, o sea los píxeles horizontales x verticales)
Además despues de cada fila de pixels (barrido horizontal), si el ancho de
la imagen no es multiplo de 4, se rellena la linea con [ancho mod 4] bytes que
contienen 0.
Por ejemplo si la imagen tuviera 42 pixeles de ancho, se
rellenaria 2 bytes (el resto de 42/4) al final de cada fila de
pixeles.
Recuerdas?
...
ancho As Long
alto As Long
...
ahora podemos leer cada uno de los píxeles de la siguiente manera:
Codigo de ejemplo para leer una imagen en Visual Basic.
Dim meta As tipoMetadatosBMP
Dim i As Long, j As Long, k as Integer, resto as Integer
Dim pixelAux As tipoPixel
Dim relleno as Byte
Open nombreBMP For Binary As #1
Get #1, , meta ' Leemos los metadatos
resto = meta.ancho mod 4 'calculamos el resto
For i = 1 To meta.alto 'Recorremos las filas
For j = 1 To meta.ancho 'Recorremos las columnas
Get #1, , pixelAux 'leemos el pixel ...
Next
For k = 1 To resto 'leemos los pixels de relleno
Get #1, , relleno
Next
Next
Close #1
Asumimos que tenemos declarado el tipo:
Public Type tipoPixel
b As Byte ' Azul
g As Byte ' verde
r As Byte ' rojo
End Type
Codigo de ejemplo para leer una imagen en C++
archivo.Open("imagen.bmp",CFile::modeCreateCFile::modeNoTruncateCFile::modeRead);
//cargamos los metadatos -----------------------------------
archivo.Read(&bm,2);
archivo.Read(&tamano,sizeof(tamano));
archivo.Read(&reservado,sizeof(reservado));
archivo.Read(&offset,sizeof(offset));
archivo.Read(&tamanoMetadatos,sizeof(tamanoMetadatos));
archivo.Read(&ancho,sizeof(ancho));
archivo.Read(&alto,sizeof(alto));
archivo.Read(&numeroPlanos,sizeof(numeroPlanos));
archivo.Read(&profundidadColor,sizeof(profundidadColor));
archivo.Read(&tipoCompresion,sizeof(tipoCompresion));
archivo.Read(&tamanoEstructura,sizeof(tamanoEstructura));
archivo.Read(&pxmh,sizeof(pxmh));
archivo.Read(&pxmv,sizeof(pxmv));
archivo.Read(&coloresUsados,sizeof(coloresUsados));
archivo.Read(&coloresImportantes,sizeof(coloresImportantes));
//----------------------------------------------------------
//Luego leemos los pixeles ---------------------------------
int resto = metadata.ancho % 4;
for (i=1;i<=metadata.alto;i++)
{ for (j=1;j<=metadata.ancho;j++)
{ archivo.Read(&varB,1); //leemos el byte azul en la variable varB
archivo.Read(&varG,1); //leemos el byte azul en la variable varB
archivo.Read(&varR,1); //leemos el byte azul en la variable varB
}
for (k=1;k<=resto;k++)
archivo.Read(&var,1); //leemos los pixels de relleno
}
archivo.Close(); //----------------------------------------------------------
El código es muy similar para cualquier otro lenguaje.
Espero les haya servido.
Comentarios y sugerencias a: carlosagreda-at-gmail.com
Publicado por Carlos Agreda en 7:39 1 comentarios
Etiquetas: Computación Grafica, Computer Science, Tratamiento Imagenes
martes, 5 de febrero de 2008
Un Mecánico de Máquinas de turing!!!
Hace tiempo que necesitaba un espacio para poder publicar curiosidades, programas, bytes sueltos que uno siempre tiene en el cerebro y es necesario volcarlos antes que la muerte se los lleve conmigo :P, asi que bienvenidos al Mecánico de Máquinas de Turing.
Publicado por Carlos Agreda en 17:58 0 comentarios
Etiquetas: Noticias GeeK