prog:oracle_multimedia_12c
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
prog:oracle_multimedia_12c [2017/05/11 20:08] – [Multimedia in der Oracle Datenbank 12c - Bildbearbeitung in PL/SQL] gpipperr | prog:oracle_multimedia_12c [2019/01/13 10:06] (aktuell) – [Multimedia in der Oracle Datenbank 12c / 18c - Bildbearbeitung in PL/SQL] gpipperr | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | =====Multimedia in der Oracle Datenbank 12c / 18c - Bildbearbeitung in PL/SQL==== | ||
+ | **Start: 05.2017** | ||
+ | |||
+ | **12c, Basis Funktion aber schon ab Oracle 8i seit 1998 verfügbar** | ||
+ | |||
+ | |||
+ | |||
+ | **18c** | ||
+ | <note important> | ||
+ | </ | ||
+ | => https:// | ||
+ | |||
+ | |||
+ | |||
+ | **Ziel:** Mit der Oracle Multimedia Option Bilder in der Datenbank bearbeiten und in APEX darstellen | ||
+ | |||
+ | |||
+ | Mit Oracle Multimedia 12c (seit 8i / 11g noch unter dem Namen Oracle interMedia vertrieben) steht dem Apex Entwickler ein reichhaltiges Werkzeug für das Metadaten Handling von Bild und Ton Daten in der Oracle Datenbank zur Verfügung. | ||
+ | |||
+ | Mit der Oracle Multimedia 12c lassen sich die Metadaten und Attribute von Multimedia Daten lesen und setzen und viele Eigenschaften von Bild Dateien, wie Größe, Rotation, Schärfe, Kontrast etc., direkt in der Datenbank bearbeiten. | ||
+ | |||
+ | Bestimmte Eigenschaften wie die Farbe eines Bildes lassen sich aus den binären Daten des Bildes ermitteln und werden damit auch suchbar. | ||
+ | |||
+ | Mit diesem umfangreichen Set an Hilfsmitteln lassen sich mit PL/SQL auch komplexere Aufgabenstellung in Oracle Apex relativ einfach integrieren. | ||
+ | |||
+ | Übersicht über die Elemente in der Datenbank: | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | |||
+ | |||
+ | Die Verarbeitung der Daten wird über Datenbank Objekt Typen durchgeführt: | ||
+ | |||
+ | * Bild Daten => ORDImage | ||
+ | * Audio Daten => ORDAudio | ||
+ | * Heterogene Daten => ORDDoc | ||
+ | * Video Daten => ORDVideo | ||
+ | |||
+ | |||
+ | Die Speicherung in einer Datenbank Tabelle | ||
+ | |||
+ | <fc # | ||
+ | * Daten und Eigenschaften über ein Objekt ansprechbar | ||
+ | * Schlankes Datenmodel | ||
+ | <fc #800000> | ||
+ | Nachteil der Speicherung als Objekt Type:</ | ||
+ | * Laderoutienen etwas komplexer | ||
+ | * Gefahr von Bugs | ||
+ | * Daten müssen für andere Tools immer extrahiert werden | ||
+ | |||
+ | |||
+ | Übersicht über möglichen Feature (11g) => http:// | ||
+ | ---- | ||
+ | |||
+ | ====Installation ==== | ||
+ | |||
+ | Siehe https:// | ||
+ | |||
+ | |||
+ | Benötigt die JAVAVM, XDB, XML Option | ||
+ | |||
+ | Legt folgende User an: | ||
+ | * ORDSYS | ||
+ | * ORDPLUGINS | ||
+ | * SI_INFORMTN_SCHEMA | ||
+ | * ORDDATA | ||
+ | * MDSYS - Oracle Multimedia Locatorset | ||
+ | |||
+ | Prüfen ob die Option auch korrekt installiert wurde: | ||
+ | <code sql> | ||
+ | SYS> | ||
+ | |||
+ | PL/SQL procedure successfully completed. | ||
+ | |||
+ | |||
+ | SYS> | ||
+ | |||
+ | VERSION | ||
+ | ------------------------------------------------- -------- | ||
+ | 12.1.0.2.0 | ||
+ | </ | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ==== Eine Beispiel Anwendung ==== | ||
+ | |||
+ | Für ein Bautagebuch sollen auch die anfallenden Bilddaten gespeichert werden. | ||
+ | |||
+ | === Einen User anlegen === | ||
+ | |||
+ | Als SYS: | ||
+ | <code sql> | ||
+ | -- create the user | ||
+ | create user conbook identified by conbook default tablespace USERS temporary tablespace TEMP; | ||
+ | alter user conbook quota unlimited on USERS; | ||
+ | |||
+ | grant connect, resource to conbook; | ||
+ | |||
+ | |||
+ | -- create the info Archive DIRECTORY | ||
+ | create or replace directory IMG_ARCHIVE as ' | ||
+ | grant read,write on directory IMG_ARCHIVE to conbook; | ||
+ | </ | ||
+ | |||
+ | Darauf achten das der Oracle User unter dem die 12c DB läuft, in meinen Fall der User ORARUN, auch die entsprechenden Rechte auf das Verzeichnis besitzt! | ||
+ | |||
+ | |||
+ | Im Dateisystem unter " | ||
+ | |||
+ | |||
+ | === Tabelle für die Bilddaten === | ||
+ | |||
+ | Für das Speichern der Bilddaten wird der Datentyp ORDSYS.ORDIMAGE eingesetzt. | ||
+ | |||
+ | |||
+ | ORDSYS.ORDIMAGE hat die folgenden " | ||
+ | < | ||
+ | ------------------- | ||
+ | -- TYPE ATTRIBUTES | ||
+ | ------------------- | ||
+ | source | ||
+ | height | ||
+ | width | ||
+ | contentLength | ||
+ | fileFormat | ||
+ | contentFormat | ||
+ | compressionFormat | ||
+ | mimeType | ||
+ | |||
+ | </ | ||
+ | |||
+ | Als User conbook | ||
+ | <code sql> | ||
+ | CREATE TABLE CONBOOK.CON_IMAGES | ||
+ | ( | ||
+ | ID | ||
+ | name | ||
+ | remarks | ||
+ | img ORDSYS.ORDIMAGE, | ||
+ | preview | ||
+ | ) | ||
+ | LOB(img.source.localData) | ||
+ | LOB(preview.source.localData) STORE AS SECUREFILE | ||
+ | ; | ||
+ | |||
+ | |||
+ | ALTER TABLE CONBOOK.CON_IMAGES ADD ( | ||
+ | CONSTRAINT CON_IMAGES_PK | ||
+ | PRIMARY KEY | ||
+ | (ID) | ||
+ | ENABLE VALIDATE); | ||
+ | </ | ||
+ | |||
+ | === Daten in die Tabelle laden === | ||
+ | |||
+ | Einfache Laderoutine: | ||
+ | |||
+ | <code sql> | ||
+ | CREATE OR REPLACE procedure loadConImg (p_id number , p_name varchar2 , p_remark varchar2) | ||
+ | as | ||
+ | | ||
+ | | ||
+ | v_ctx RAW(64) := NULL; | ||
+ | BEGIN | ||
+ | -- save metadata and return a referenz on the img object | ||
+ | insert into CON_IMAGES (ID, NAME, REMARKS, | ||
+ | values (p_id, | ||
+ | RETURNING img INTO v_img_orig; | ||
+ | |||
+ | | ||
+ | -- read the image data to the temporary object | ||
+ | v_img_orig.importFrom(v_ctx,' | ||
+ | |||
+ | -- insert the temporary object into the image tabee | ||
+ | UPDATE CON_IMAGES SET img=v_img_orig WHERE id=p_id; | ||
+ | commit; | ||
+ | | ||
+ | | ||
+ | SELECT img.IMG, | ||
+ | INTO v_img_orig, | ||
+ | FROM CON_IMAGES img | ||
+ | WHERE img.id=p_id | ||
+ | FOR UPDATE; | ||
+ | |||
+ | begin | ||
+ | -- create the preview image | ||
+ | v_img_orig.processCopy(' | ||
+ | -- only copy | ||
+ | --v_img_orig.copy(v_img_preview); | ||
+ | EXCEPTION | ||
+ | WHEN ORDSYS.ORDImageExceptions.NULL_DESTINATION THEN | ||
+ | DBMS_OUTPUT.PUT_LINE(' | ||
+ | WHEN ORDSYS.ORDImageExceptions.DATA_NOT_LOCAL THEN | ||
+ | DBMS_OUTPUT.PUT_LINE(' | ||
+ | WHEN ORDSYS.ORDImageExceptions.NULL_LOCAL_DATA THEN | ||
+ | DBMS_OUTPUT.PUT_LINE(' | ||
+ | when others then | ||
+ | | ||
+ | end; | ||
+ | | ||
+ | UPDATE CON_IMAGES SET preview=v_img_preview WHERE id=p_id; | ||
+ | commit; | ||
+ | |||
+ | END; | ||
+ | / | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | Damit das Image Objekt auch verwendet werden kann, muss es zuvor initialisiert werden. | ||
+ | |||
+ | Das kann ohne weitere Eigenschaften " | ||
+ | |||
+ | Beispiel für das Laden mit der obigen Routine über SQL*Plus: | ||
+ | <code sql> | ||
+ | delete CON_IMAGES; | ||
+ | |||
+ | commit; | ||
+ | |||
+ | set serveroutput on | ||
+ | |||
+ | begin | ||
+ | for i in 1 .. 13 | ||
+ | loop | ||
+ | loadConImg ( p_id => i | ||
+ | , p_name | ||
+ | , p_remark => 'This is image ' | ||
+ | end loop; | ||
+ | end; | ||
+ | / | ||
+ | |||
+ | select * from CON_IMAGES; | ||
+ | </ | ||
+ | |||
+ | === Objekt Eigenschaften von ORDSYS.ORDImage ausgeben === | ||
+ | |||
+ | Die wichtigsten Metadaten eines Bildes werden in dem Objekt ORDSYS.ORDImage als Attribute gespeichert. | ||
+ | |||
+ | Ausgeben mit: | ||
+ | <code sql> | ||
+ | set serveroutput on | ||
+ | |||
+ | DECLARE | ||
+ | | ||
+ | BEGIN | ||
+ | | ||
+ | INTO v_image | ||
+ | FROM CON_IMAGES img | ||
+ | WHERE id = 1; | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | END; | ||
+ | / | ||
+ | |||
+ | </ | ||
+ | |||
+ | Bzw. in SQL ausgeben: | ||
+ | |||
+ | <code sql> | ||
+ | select | ||
+ | , i.img.getHeight() height | ||
+ | , i.img.getWidth() width | ||
+ | , i.img.getMimetype() mimetype | ||
+ | , i.img.getFileFormat() fileformat | ||
+ | , i.img.getContentLength() length | ||
+ | from CON_IMAGES i ORDER BY i.id | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | ===EXIF Daten aus dem Bildern auslesen=== | ||
+ | |||
+ | |||
+ | Beispiel: | ||
+ | <code sql> | ||
+ | set serveroutput on | ||
+ | |||
+ | DECLARE | ||
+ | v_image | ||
+ | v_metadata | ||
+ | BEGIN | ||
+ | |||
+ | SELECT img | ||
+ | INTO v_image | ||
+ | FROM CON_IMAGES img | ||
+ | WHERE id = 1; | ||
+ | |||
+ | v_metadata := v_image.getMetadata(' | ||
+ | |||
+ | -- print the namespace of each metadata document | ||
+ | FOR i in 1..v_metadata.count LOOP | ||
+ | DBMS_OUTPUT.PUT_LINE(' | ||
+ | | ||
+ | DBMS_OUTPUT.PUT_LINE(' | ||
+ | END LOOP; | ||
+ | | ||
+ | |||
+ | EXCEPTION | ||
+ | WHEN ORDSYS.ORDImageExceptions.NULL_LOCAL_DATA THEN | ||
+ | DBMS_OUTPUT.PUT_LINE(' | ||
+ | WHEN ORDSYS.ORDImageExceptions.NULL_SOURCE THEN | ||
+ | DBMS_OUTPUT.PUT_LINE(' | ||
+ | WHEN OTHERS THEN | ||
+ | RAISE; | ||
+ | END; | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | Am einfachsten wird das am Anfang beim Laden gelesen und dann gleich in einer eigenen CLOB / XML Spalte gespeichert um später weiter verarbeitet werden zu können. | ||
+ | |||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ---- | ||
+ | |||
+ | |||
+ | |||
+ | ====APEX 5.1 Integration ==== | ||
+ | |||
+ | === Ein Bild darstellen === | ||
+ | |||
+ | In Apex 5 kann sehr einfach ein Bild auf ein auf einer Seite über ein Page Item vom Typ **" | ||
+ | |||
+ | Dazu muss aber das Bild in einer BLOB Spalte vorliegen! | ||
+ | |||
+ | In unseren Fall liegt das Bild aber in einem Objekt vom Typ ORDSYS.ORDImage, | ||
+ | |||
+ | |||
+ | Als **" | ||
+ | |||
+ | SQL: | ||
+ | <code sql> | ||
+ | SELECT img.preview.source.localData | ||
+ | FROM CON_IMAGES img | ||
+ | WHERE img.id=1 | ||
+ | </ | ||
+ | |||
+ | {{ : | ||
+ | ---- | ||
+ | |||
+ | === Bilder in einem Bericht darstellen === | ||
+ | |||
+ | Leider geht es nicht so einfach mit einen " | ||
+ | |||
+ | |||
+ | Wird nun die Image Spalte auf den Typ " | ||
+ | |||
+ | SQL für die BLOB View: | ||
+ | <code sql> | ||
+ | CREATE OR REPLACE VIEW CONBOOK.V_CON_IMAGES_BLOB | ||
+ | AS | ||
+ | SELECT | ||
+ | , NAME | ||
+ | , img.img.getMimetype() mimetype | ||
+ | , REMARKS | ||
+ | , img.img.source.localData IMG | ||
+ | , img.PREVIEW.source.localData as PREVIEW | ||
+ | FROM CON_IMAGES img; | ||
+ | </ | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | |||
+ | |||
+ | Fehler <fc # | ||
+ | |||
+ | In der eigentlichen Berichtsabfrage darf nicht der BLOB des Bildes, sondern die Größe des Bildes muss referenziert werden. | ||
+ | |||
+ | <code sql> | ||
+ | SELECT | ||
+ | , ID | ||
+ | , NAME | ||
+ | , REMARKS | ||
+ | FROM CON_IMAGES img order by ID | ||
+ | </ | ||
+ | |||
+ | Und schon funktioniert es! | ||
+ | |||
+ | Siehe auch => http:// | ||
+ | |||
+ | ---- | ||
+ | |||
+ | === Bild bearbeiten=== | ||
+ | |||
+ | |||
+ | Über die Methode http:// | ||
+ | |||
+ | |||
+ | Dazu wird in APEX einfach diese Funktion als Source für ein Image Display Item aufgerufen und dabei das entsprechende Kommando übergeben. | ||
+ | |||
+ | In der folgenden Routine wird die Watermark Funktion verwandt um im Fehlerfall den SQL Fehler | ||
+ | |||
+ | Achtung! Hier ist noch ein böser Bug! der Temporäre Speicher wird nicht freigeben wenn die Watermark Funktion verwendet wird! | ||
+ | |||
+ | Beispiel Code um ein Bild zu verarbeiten: | ||
+ | <code sql> | ||
+ | create or replace function imgConverter(p_img_id number, | ||
+ | return blob | ||
+ | is | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | |||
+ | --- Error handling | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | begin | ||
+ | -- get the original image | ||
+ | SELECT img.IMG | ||
+ | INTO v_img_orig | ||
+ | FROM CON_IMAGES img | ||
+ | WHERE img.id=p_img_id; | ||
+ | |||
+ | -- init the blob | ||
+ | | ||
+ | | ||
+ | |||
+ | begin | ||
+ | | ||
+ | ORDSYS.ORDImage.processCopy( | ||
+ | | ||
+ | , | ||
+ | ,dest => v_img_blob); | ||
+ | | ||
+ | v_error: | ||
+ | | ||
+ | EXCEPTION | ||
+ | WHEN ORDSYS.ORDImageExceptions.NULL_DESTINATION THEN | ||
+ | v_message: | ||
+ | v_error: | ||
+ | WHEN ORDSYS.ORDImageExceptions.DATA_NOT_LOCAL THEN | ||
+ | v_message: | ||
+ | v_error: | ||
+ | WHEN ORDSYS.ORDImageExceptions.NULL_LOCAL_DATA THEN | ||
+ | v_message: | ||
+ | v_error: | ||
+ | when others then | ||
+ | v_message: | ||
+ | v_error: | ||
+ | end; | ||
+ | |||
+ | if v_error then | ||
+ | -- print the error into the image as Watermark | ||
+ | | ||
+ | | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | |||
+ | | ||
+ | dbms_lob.createtemporary(v_img_blob_error, | ||
+ | |||
+ | ORDSYS.ORDImage.applyWatermark( | ||
+ | | ||
+ | , | ||
+ | ,dest => v_img_blob_error | ||
+ | , | ||
+ | , | ||
+ | ); | ||
+ | v_img_work: | ||
+ | ----------------------------------------- | ||
+ | -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 | ||
+ | -- dummy process to free memory | ||
+ | -- BUG with applyWatermark !! | ||
+ | -- if you call ORDSYS.ORDImage.processCopy the memory will be freed sucessfull | ||
+ | -- strange behavior | ||
+ | -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 | ||
+ | ----------------------------------------- | ||
+ | ORDSYS.ORDImage.processCopy( | ||
+ | | ||
+ | , | ||
+ | ,dest => v_img_blob); | ||
+ | else | ||
+ | v_img_work: | ||
+ | end if; | ||
+ | |||
+ | | ||
+ | |||
+ | -- Free the temporary LOB | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | end imgConverter; | ||
+ | </ | ||
+ | |||
+ | Demnächst Mehr | ||
+ | |||
+ | == Problem mit ORDImage.applyWatermark - data cartridge error IMG-00003: exhausted memory while processing image IMG-003: out of memory in (native) awt jpeg decode- == | ||
+ | |||
+ | Da ich ja im obigen Code den BLOB nicht mehr so wirklich freigeben kann, laufen ich schnell nach ein paar Versuchen bei den obigen Oracle Fehler.... daher auch das etwas umständliche Kopieren der LOB's, leider hat das nicht wirklich geholfen, nach 8 Versuchen ist Schluss.... aber nur wenn die Methode **ORDImage.applyWatermark** betroffen ist! | ||
+ | |||
+ | < | ||
+ | ERROR: | ||
+ | ORA-29400: data cartridge error | ||
+ | IMG-00003: exhausted memory while processing image | ||
+ | IMG-003: out of memory in (native) awt jpeg decode | ||
+ | ORA-06512: at " | ||
+ | ORA-06512: at " | ||
+ | ORA-06512: at " | ||
+ | ORA-06512: at " | ||
+ | ORA-06512: at " | ||
+ | ORA-06512: at line 1 | ||
+ | </ | ||
+ | |||
+ | Erste Lösungen: | ||
+ | |||
+ | Java Pool Size vergrößert | ||
+ | |||
+ | <code sql> | ||
+ | alter system set java_pool_size=256M scope=memory sid=' | ||
+ | |||
+ | -- kontrolle der aktuellen Verwendung mit: | ||
+ | |||
+ | select * from v$javapool; | ||
+ | |||
+ | </ | ||
+ | |||
+ | Dann funktioniert es etwas länger, Speicher läuft trotzdem voll ..... | ||
+ | |||
+ | Laut Support Node => " | ||
+ | |||
+ | Ärgerlich ... | ||
+ | |||
+ | |||
+ | <fc # | ||
+ | |||
+ | Nach dem Aufruf von **ORDSYS.ORDImage.applyWatermark** nochmals eine gültige Operation mit **ORDSYS.ORDImage.processCopy** ausführen um den Stack der Session wieder richtig aufzuräumen. | ||
+ | |||
+ | Funktioniert, | ||
+ | |||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | === Bilder hochladen === | ||
+ | |||
+ | Wie aber nun die Bilder über die Weboberfläche hochladen? | ||
+ | |||
+ | |||
+ | In APEX 5 wird intern die Tabelle APEX_APPLICATION_TEMP_FILES für das hochladen von Dateien verwendet. | ||
+ | |||
+ | |||
+ | Aus dieser Tabelle holen wir uns die Daten und schreiben die Daten in unsere Bild Tabelle. | ||
+ | |||
+ | |||
+ | Danach nicht vergessen das Bild in der APEX_APPLICATION_TEMP_FILES auch wieder zu löschen ( View auf wwv_flow_file_objects$)! | ||
+ | |||
+ | |||
+ | Um die Datei auszuwählen ein Page Item vom Typ "File Browse" | ||
+ | |||
+ | Einen Submit Button auf der Page anlegen ( Action " | ||
+ | |||
+ | Für die eigentliche Logik des Umkopieren der Daten dann ein Stück PL/SQL verwenden um die Daten in unsere Struktur einzulesen. | ||
+ | |||
+ | |||
+ | |||
+ | Der PL/SQL code für den "After Submit" | ||
+ | <code sql> | ||
+ | declare | ||
+ | v_file_count pls_integer: | ||
+ | | ||
+ | v_img_orig ORDSYS.ORDImage; | ||
+ | v_img_preview ORDSYS.ORDImage; | ||
+ | | ||
+ | v_id CON_IMAGES.id%type; | ||
+ | | ||
+ | v_message varchar2(4000): | ||
+ | | ||
+ | begin | ||
+ | if : | ||
+ | | ||
+ | | ||
+ | |||
+ | select count(ID) into v_file_count | ||
+ | from apex_application_temp_files | ||
+ | where name = : | ||
+ | |||
+ | if v_file_count > 0 then | ||
+ | for rec in (select | ||
+ | id, | ||
+ | application_id, | ||
+ | name, | ||
+ | filename, | ||
+ | mime_type, | ||
+ | created_on, | ||
+ | blob_content | ||
+ | from apex_application_temp_files where name = : | ||
+ | begin | ||
+ | |||
+ | v_message:= v_message||' | ||
+ | | ||
+ | values ( CON_IMAGES_SEQ.nextval | ||
+ | , rec.filename | ||
+ | , rec.filename ||' Mime type' | ||
+ | , ORDSYS.ORDImage.init() | ||
+ | , ORDSYS.ORDImage.init() ) | ||
+ | RETURNING id,img INTO v_id, | ||
+ | |||
+ | v_img_orig: | ||
+ | |||
+ | | ||
+ | commit; | ||
+ | |||
+ | --create trumbnail image | ||
+ | SELECT img.IMG, | ||
+ | INTO v_img_orig, | ||
+ | FROM CON_IMAGES img | ||
+ | WHERE img.id=v_id | ||
+ | FOR UPDATE; | ||
+ | |||
+ | |||
+ | -- create the preview image | ||
+ | v_img_orig.processCopy(' | ||
+ | -- only copy | ||
+ | --v_img_orig.copy(v_img_preview); | ||
+ | |||
+ | |||
+ | UPDATE CON_IMAGES SET preview=v_img_preview WHERE id=v_id; | ||
+ | commit; | ||
+ | |||
+ | | ||
+ | WHEN ORDSYS.ORDImageExceptions.NULL_DESTINATION THEN | ||
+ | v_message: | ||
+ | WHEN ORDSYS.ORDImageExceptions.DATA_NOT_LOCAL THEN | ||
+ | | ||
+ | WHEN ORDSYS.ORDImageExceptions.NULL_LOCAL_DATA THEN | ||
+ | | ||
+ | when others then | ||
+ | v_message: | ||
+ | end; | ||
+ | |||
+ | end loop; | ||
+ | | ||
+ | -- clean the tempfile | ||
+ | begin | ||
+ | delete apex_application_temp_files | ||
+ | commit; | ||
+ | EXCEPTION | ||
+ | when others then | ||
+ | | ||
+ | end; | ||
+ | end if; | ||
+ | end if; | ||
+ | | ||
+ | apex_application.g_print_success_message := '< | ||
+ | end; | ||
+ | </ | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ====Bilder vergleichen ==== | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Wir legen uns daher nun eine Tabelle mit ein paar Basis Bilder an um den Vergleichsalgorithmus zu testen. | ||
+ | |||
+ | |||
+ | <code sql> | ||
+ | drop table con_img_templates; | ||
+ | |||
+ | CREATE TABLE con_img_templates ( | ||
+ | | ||
+ | ,name VARCHAR2(256) NOT NULL | ||
+ | , | ||
+ | , | ||
+ | , | ||
+ | ) | ||
+ | LOB(img_template.source.localData) | ||
+ | ; | ||
+ | |||
+ | |||
+ | ALTER TABLE CONBOOK.con_img_templates ADD ( | ||
+ | CONSTRAINT con_img_templates_PK | ||
+ | PRIMARY KEY | ||
+ | (ID) | ||
+ | ENABLE VALIDATE); | ||
+ | |||
+ | create sequence CONBOOK.con_img_templates_SEQ; | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | In diese Tabelle laden wir nun ein blaues, | ||
+ | |||
+ | <code sql> | ||
+ | CREATE OR REPLACE procedure CONBOOK.loadTemplateImg (p_id number | ||
+ | , p_name varchar2 | ||
+ | , p_remark varchar2) | ||
+ | as | ||
+ | |||
+ | | ||
+ | | ||
+ | v_ctx RAW(4000) := NULL; | ||
+ | BEGIN | ||
+ | |||
+ | -- save metadata and return a referenz on the img object | ||
+ | insert into con_img_templates (ID, NAME, REMARKS, | ||
+ | values (p_id, | ||
+ | RETURNING img_template, | ||
+ | | ||
+ | -- read the image data to the temporary object | ||
+ | v_img_orig.import(v_ctx); | ||
+ | v_img_sig.generateSignature(v_img_orig); | ||
+ | |||
+ | -- insert the temporary object into the image tabee | ||
+ | UPDATE con_img_templates SET img_template=v_img_orig, | ||
+ | commit; | ||
+ | |||
+ | END; | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | Laden: | ||
+ | <code sql> | ||
+ | delete con_img_templates; | ||
+ | |||
+ | commit; | ||
+ | |||
+ | set serveroutput on | ||
+ | |||
+ | begin | ||
+ | | ||
+ | loadTemplateImg ( p_id => con_img_templates_SEQ.nextval | ||
+ | , p_name | ||
+ | , p_remark => 'This is image gruen' | ||
+ | | ||
+ | loadTemplateImg ( p_id => con_img_templates_SEQ.nextval | ||
+ | , p_name | ||
+ | , p_remark => 'This is image weiss' | ||
+ | | ||
+ | loadTemplateImg ( p_id => con_img_templates_SEQ.nextval | ||
+ | , p_name | ||
+ | , p_remark => 'This is image blau' | ||
+ | | ||
+ | loadTemplateImg ( p_id => con_img_templates_SEQ.nextval | ||
+ | , p_name | ||
+ | , p_remark => 'This is image gelb' | ||
+ | | ||
+ | loadTemplateImg ( p_id => con_img_templates_SEQ.nextval | ||
+ | , p_name | ||
+ | , p_remark => 'This is image rot' | ||
+ | end; | ||
+ | / | ||
+ | |||
+ | select * from con_img_templates; | ||
+ | commit; | ||
+ | </ | ||
+ | |||
+ | |||
+ | <code sql> | ||
+ | alter table con_images add (signature ORDSYS.ORDImageSignature); | ||
+ | update con_images set signature=ORDImageSignature.init(); | ||
+ | </ | ||
+ | |||
+ | Vergleichen über den Score: | ||
+ | |||
+ | <code sql> | ||
+ | DECLARE | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | v_sim float; | ||
+ | | ||
+ | | ||
+ | BEGIN | ||
+ | |||
+ | -- read image | ||
+ | select img, | ||
+ | |||
+ | | ||
+ | |||
+ | for rec in (select img_template | ||
+ | , | ||
+ | ,name from con_img_templates | ||
+ | loop | ||
+ | -- Compare two images for similarity based on image color: | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | end loop; | ||
+ | |||
+ | | ||
+ | |||
+ | END; | ||
+ | / | ||
+ | |||
+ | </ | ||
+ | |||
+ | see => https:// | ||
+ | |||
+ | |||
+ | Um ein Bild zu suchen muss immer zuvor ein Beispiel Bild vorgegeben werden, mit diesem wird verglichen | ||
+ | See => https:// | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ---- | ||
+ | |||
+ | |||
+ | ==== Quellen ==== | ||
+ | |||
+ | ==Doku== | ||
+ | |||
+ | Oracle Multimedia User's Guide 12c => http:// | ||
+ | |||
+ | |||
+ | ==Support== | ||
+ | |||
+ | * Information Center: Oracle Multimedia/ | ||
+ | |||
+ | ==Web== | ||
+ | | ||
+ | Bücher: | ||
+ | |||
+ | * https:// | ||
+ | | ||
+ | Blogs: | ||
+ | |||
+ | * https:// | ||
+ | * http:// | ||
+ | * https:// | ||
+ | * http:// | ||
+ | |||
+ | Bild in Apex per Java Script Modal größer darstellen | ||
+ | * http:// | ||
+ | |||
+ | |||
+ | ==Audio== | ||
+ | |||
+ | * http:// |
prog/oracle_multimedia_12c.txt · Zuletzt geändert: 2019/01/13 10:06 von gpipperr