Procesamiento de imagenes en Oracle Database 11g
19/12/2013 -
Existen varias opciones para almacenar imágenes en BBDD Oracle. La manera más común es utilizar una columna de tipo BLOB y cargar una imagen como contenido binario.
A partir de la versión 11g, Oracle ha introducido Oracle Multimedia (anteriormente conocido como Oracle InterMedia), una extensión que permite guardar imágenes, audio, vídeo y otra información multimedial.
Oracle Multimedia introduce los objetos de tipo ORDAudio, ORDDoc, ORDImage, ORDVideo, and SI_StillImage y métodos para:
- Extraer metadatos y atributos de datos multimediales
- Incrustar metadatos generados por otras aplicaciones en ficheros imagen
- Incorporar datos multimediales a partir de Oracle Multimedia, web servers, file systems, y otros servidores
- Ejecutar operaciones y aplicar transformaciones a imágenes
En otras palabras, Oracle Multimedia permite manipular imágenes con una simple instrucción SQL.
En este post, el enfoque será en las operaciones que se pueden realizar sobre imágenes.
Empezamos creando una tabla donde guardaremos una imagen en formato TIFF.
CREATE TABLE AVT_IMG ( ID NUMBER, TIFF_IMG ORDSYS.ORDImage );
Además se crea un directorio que apunte a la ubicación de las imágenes.
CREATE OR REPLACE DIRECTORY avt_img_dir as 'C:Imagenes_Blog';
Construimos un objeto ORDImage a partir de la imagen y lo insertamos en la tabla que acabamos de crear.
-- Inicialización del objeto ORDImage INSERT INTO AVT_IMG VALUES(1,ORDImage.init()); COMMIT; -- Carga de la imagen en el campo ORDImage DECLARE obj ORDSYS.ORDImage; ctx RAW(64) := NULL; BEGIN -- El metodo import() carga las propiedades multimediales de la imagen select TIFF_IMG into obj from AVT_IMG where ID = 1 for update; obj.setSource('FILE', 'AVT_IMG_DIR', 'avanttic_logo.tif'); obj.import(ctx); update AVT_IMG set TIFF_IMG = obj where id = 1; commit; END; /
Utilizando los métodos del objeto ORDSYS.ORDImage se pueden visualizar las propiedades de la imagen.
DECLARE image ORDSYS.ORDImage; compression_format VARCHAR2(4000); img_height NUMBER; img_width NUMBER; content_size NUMBER; metav XMLSequenceType; properties_match BOOLEAN; BEGIN -- Cargamos la imagen en una variable SELECT TIFF_IMG INTO image FROM AVT_IMG WHERE ID=1; -- Averiguamos que sea posible leer las propiedades de la imagen properties_match := image.checkProperties(); IF properties_match THEN DBMS_OUTPUT.PUT_LINE('Check Properties succeeded'); ELSE DBMS_OUTPUT.PUT_LINE('Check Properties failed'); END IF; -- Extraemos las propiedades de la imagen compression_format := image.getCompressionFormat(); img_height := image.getHeight(); img_width := image.getWidth(); content_size := image.getContentLength(); DBMS_OUTPUT.PUT_LINE('Formato de compresión: ' || compression_format); DBMS_OUTPUT.PUT_LINE('Alto: ' || img_height); DBMS_OUTPUT.PUT_LINE('Ancho: ' || img_width); DBMS_OUTPUT.PUT_LINE('Tamaño: ' || content_size); COMMIT; END; /
El resultado de este bloque de còdigo es:
y coincide con las propiedades de la imagen que estamos utilizando como ejemplo.
Añadimos a la tabla las siguientes columnas:
ALTER TABLE AVT_IMG ADD (JPEG_IMG ORDSYS.ORDImage, TIFF_BLOB BLOB, JPEG_BLOB BLOB);
para poder guardar el contenido binario (sin metadatos) de la imagen y su copia en formato JPEG.
Para extraer el contenido BLOB de la imagen (sin metadatos), existe el método getContent().
UPDATE AVT_IMG SET TIFF_BLOB = ordsys.ordimage.getContent(TIFF_IMG); COMMIT;
Para realizar una conversión de formato, por ejemplo de TIFF a JPEG, se puede utilizar el método processCopy().
DECLARE imgTiff blob; imgJpeg blob; BEGIN UPDATE AVT_IMG SET JPEG_BLOB = empty_blob() RETURNING TIFF_BLOB, JPEG_BLOB INTO imgTiff, imgJpeg; -- El metodo recibe como parametros: -- * imagen origen -- * cadena que especifica el tipo de transformación a realizar -- * imagen destino ordsys.ordimage.processCopy(imgTiff, 'fileformat=jpeg', imgJpeg); UPDATE AVT_IMG SET JPEG_BLOB = imgJpeg; COMMIT; END; /
Se pueden realizar conversiones entre los siguientes formatos: BMPF, CALS, GIFF, JFIF, PBMF, PGMF, PICT, PNGF, PNMF, PPMF, RASF, RPIX, TGAF, TIFF, WBMP.
Para crear el objeto JPEG_IMG a partir del BLOB en JPEG podemos utilizar la instrucción:
UPDATE AVT_IMG SET JPEG_IMG = ordsys.ordimage(ordsys.ordsource(JPEG_BLOB, null, null, null, sysdate, 1) ,null, null, null, null, null, null, null );
Los métodos process() (que sobrescribe la imagen origen con el resultado de la transformación) y processCopy() permiten realizar transformaciones más complejas como por ejemplo, ajustar el contraste, escalar o rotar la imagen. El ejemplo siguiente realiza una rotación de 90 grados de la imagen en JPEG.
DECLARE imgTiff blob; imgJpeg blob; BEGIN UPDATE AVT_IMG set JPEG_BLOB=JPEG_BLOB RETURNING JPEG_BLOB INTO imgJpeg; ordsys.ordimage.process(imgJpeg, 'rotate=90'); UPDATE AVT_IMG SET JPEG_BLOB = imgJpeg; COMMIT; END;
Con estos ejemplos se ha querido dar una breve demostración de que Oracle Multimedia ofrece una solución versátil para el tratamiento de datos multimediales.
Para más información, consultar la documentación oficial en http://www.oracle.com/pls/db112/portal.portal_db?selected=7&frame=#oracle_multimedia.