动态显示BLOB

时间:2011-09-20 08:01:39

标签: oracle oracle-apex

最近我一直在研究一个相当适度的应用程序,它列出了联系人。单击详细信息链接时,弹出窗口会显示更多详细信息和该联系人的图像。 这个基于的表包含一个列photo_reference,它保存了/ i /下文件夹的路径。通过此设置,可以轻松地使图像适用于每个联系人。 我展示的弹出窗口是我放入该区域页脚的一堆htmlcode,并隐藏起来。

<div id="contact_popup" class="contact_pop">
   <div class="contact_pop_imgcontainer">
      <img id="id_photo" class="contact_pop" />
   </div> 
</div>

单击详细信息后,我通过应用程序进程检索数据,并显示此容器的模式对话框。

现在范围已经改变:用户需要能够上传自己的图像。所以,我开始工作并将其设置为将图像上传到wwv_flow_files,然后我将它们移动到新的contact_image表。到现在为止还挺好。但现在我想要显示这些图片,在这里我有点卡住了。 *我可以在我的IR中包含一个列,并在其上放置一个带有图像的blob格式掩码。我有这个工作,但很烦人。我的图像表具有字段'ID'作为主键。我的联系人表格也有'ID'作为PK。 由于IMAGE:APXT_CONTACTS_IMG:SMALL_PHOTO:ID::::::inline:将ID指定为PK,因此它使用来自联系人表的ID。  表之间的链接是APXT_CONTACTS.CONTACT_IMAGE_ID -> APXT_CONTACTS_IMG.ID。 我可以使其工作的方式是将图像表中的id字段重命名为contact_image_id。 (为什么格式掩码不能将它所基于的列作为值:()。  然后我可以隐藏列,并使用javascript将图像显示在我的弹出窗口中。但是,这会为所选行的数量预加载所有图像,这并不完全是坏事,但我正在寻找替代方案。

  • get_blob_file_src似乎对我没用,因为参数的使用有限(文件浏览项,id字段),即使这样,我可以通过ajax回调使用它吗?

  • 我宁愿能够通过ajax获取图像blob然后显示在我的弹出窗口中,但我不知道如何做到这一点。我已经制作了一个存储过程来获取要下载的文件并从应用程序进程(ajax回调)中调用它,并且使用firebug我可以看到帖子/响应,但我不知道如何将其显示为图像

使用Javascript:

function cimg(){
   var get = new htmldb_Get(null, &APP_ID., "APPLICATION_PROCESS=get_img", &APP_PAGE_ID.);
   get.addParam('x01', 25);
   var greturn = get.get();
   alert(greturn);
   var pic = new Image();
   pic.onload = function(){
      document.body.appendChild(pic);
   };
   pic.src = greturn;
};

页面处理:

begin
   show_small_photo(apex_application.g_x01);
end;

存储过程:

create or replace procedure "SHOW_SMALL_PHOTO"
(p_contact_image_id IN NUMBER)
is
   v_mime      apxt_contacts_img.mime_type%type;
   v_length    NUMBER;
   v_filename  apxt_contacts_img.filename%type;
   v_lob       BLOB;
begin
    SELECT mime_type, lengthb(small_photo), filename, small_photo
    INTO v_mime, v_length, v_filename, v_lob
    FROM apxt_contacts_img
    WHERE id = p_contact_image_id;

    OWA_UTIL.mime_header (NVL (v_mime, 'application/octet'), FALSE);

    HTP.p ('Content-length: ' || v_length);
    -- needed?
    --HTP.p ('Content-Disposition: attachment; filename="'||v_filename||'"');
    OWA_UTIL.http_header_close;
    wpg_docload.download_file (v_lob);
end;

(我宁愿不必将执行权授予public并通过链接调用存储过程。) 这样我只需要加载点击链接的图片。虽然这段代码不起作用。我得到警报,看到一堆那些奇怪的字符,所以我认为这是blob说话。但是我没有在任何地方获得图像。

我错过了什么吗?做错了什么?我完全没有线索。

而不是我现有的代码,我可以通过创建另一个页面,并且处理页面项目及其值来尝试获得相同的布局,然后通过ajax获取该页面,而不是我的现有代码。 我主要是试图最小化对现有应用程序的影响(=工作),所以我不必再次更改页面。

TL; DR:是否可以从不在报表查询中的表中检索和显示图像blob,最好是通过ajax?

这是11g db

上的Apex 4.02

谢谢, 汤姆

3 个答案:

答案 0 :(得分:2)

对于它可能涉及的人,这是我如何解决/解决它:

我选择了fetch-another-page路线。也许在我的操作中我太技术或太难了,但事后我觉得我可以把它归结为: “通过ajax检索图像blob并显示它”。 所以,如果这对任何人都响了,请告诉我。

也有一些纠正: 我的图像表是联系人表的子项,因此我的FK之间是images.contact_id - &gt; contact.id

我在我的应用程序中创建了一个新页面,并根据我的图像表放置了一个表单。我只显示2个“显示图像”类型(缩略图和原始大小)和2个隐藏项目,“ID”和“CONTACT_ID”。我删除了所有不必要的东西:没有按钮,没有DML进程,没有标签,没有模板。 自动行获取过程将“主键”作为我的联系人ID,因此我可以使用url中的contact_id调用页面(这样我就不必进行额外的选择来检索图像表中的正确ID)。 Page120: form page for fetching

在页面上我需要图片,然后在需要时获取包含照片的页面(即:当点击详细图标并显示我的弹出窗口时)。 在此函数中调用以下代码段 (这里只有代码'缺失'是我调用另一个页面进程来获取json格式的联系人详细信息)

//page 120 only holds the 2 images for a contact. Due to images being in
//blobs and no easy way to dynamically fetch them, i made a small
//form with the 2 photos on, and id + contact_id
//(contact_id made PK for the ARF-process, since this is what is worked with)
//The page is pulled in, and the photos retrieved

//htmldb_get does not do the job! It only pulls the page from cache, which isnt what i want

// arrays with the arguments and their values for the post
var vArgs = new Array();
var vVals = new Array();

vArgs.push("P120_CONTACT_ID");
vVals.push(cid);

$.post('wwv_flow.show', 
       {"p_request"      : "NULL",
        "p_flow_id"      : $v('pFlowId'),
        "p_flow_step_id" : "120",
        "p_instance"     : $v('pInstance'),
        "p_arg_names"    : vArgs,
        "p_arg_values"   : vVals}, 
       function(data){
         var oContainerSmall = $("#id_photo_container").empty(),
             oSmallPhoto = $(data).find("#P120_SMALL_PHOTO").attr({"id":"id_photo",
                                                                   "alt":oContact.lastname + " " + oContact.firstname}),
             oLargePhoto = $(data).find("#P120_LARGE_PHOTO").attr("alt",oContact.lastname + " " + oContact.firstname);

         $("#large_photo_container").empty().append(oLargePhoto);
         $("#large_photo_container").css({"display": "block", "visibility": "hidden"});

         //Why remove and remake the container? 
         //for some reason i couldn't find out, the image width and height get reset to 0 after 
         // an initial display of the enlarged picture and closing its dialogbox.
         //I assume it is an apex+css+javascript issue.
         //The only fix i was able to find was to remove the div and remake a new one.
         // There have to be some properties set on the div and/or its children through
         // the closing of the popup dialog (for the larger picture), 
         // which then prevents subsequent calls to get the correct values.
         $("#large_photo_container").remove();
         var oContainerLarge = $("<div></div>").attr("id","large_photo_container").css({"display":"block", "visibility":"hidden"});
         oContainerLarge.append(oLargePhoto);
         $("body").append(oContainerLarge);

         //Hardcoded value here! Adapt when necessary
         if($("#id_contact_type").val() == "Conference Room"){
            var oLink = $("<a/>").attr("href", "#")
                                .click(function(event){
                                         explode_headshot(event, this);
                                       });
            oContainerSmall.append(oLink.append(oSmallPhoto));
         } else {
            oContainerSmall.append(oSmallPhoto);
         };

         $("#contact_popup").dialog({modal: true,
                                     width: 750,
                                     resizable: false, 
                                     title: oContact.lastname + " " + oContact.firstname,
                                     close: function(event, ui){
                                       $("#id_photo").attr({"src": "", "alt": ""});
                                    }});
      });

我不会称之为理想,但它确实有效,而这就是我现在所需要的一切:)

答案 1 :(得分:0)

显示图像可以像创建类型的项目一样简单:“显示图像”。设置:“sql语句返回的Blob列”。

然后选择正确的行的SQL语句:

选择blob_content 来自my_bitmap_table 其中ID = ...

答案 2 :(得分:0)

我做了一个非常类似的应用程序,用于显示联系方式,包括几个月前的顶级照片。

我发现这个网页非常有用:

http://blog.hilandco.com/2010/05/how-to-show-blob-type-column-as-image.html