перевод с OLE BLOB на растровое изображение в Powerbuilder - PullRequest
0 голосов
/ 19 октября 2011

Мне нужно выполнить преобразование данных из старой базы данных ms sql 6.5, теперь у меня возникла проблема с хранилищем изображений внутри ms sql 6.5, все эти изображения хранятся в виде ole-данных, что означает, что на самом деле старое приложение, которое взаимодействует с этой таблицей ms sql 6.5, действительно хранитизображение как оле в типе изображения.Когда я выбираю BLOB-объект в BLOB-объекте в Powerbuilder, мне нужно отправить этот BLOB-объект в ole_1.objectdata, а затем преобразовать этот ole_1.objectdata в нужную длину, чтобы вывести его в файл растрового изображения на диске, я извлек этот код перевода из expert-обмен на "Печать BLOB-объектов в bmp / ​​jpg" (опубликовано Buasuwan, однако не может получить DLL, поскольку сообщение является старым сообщением).Он отлично работает для 60% моего блоба, преобразованного в растровое изображение, в то время как остальные выдают пустое представление с соответствующим размером файла, просто не могу его просмотреть. Вот код, я хотел бы, чтобы некоторые гуру помогли мне с переводом ole в растровое изображение

    Blob lb_image

    SelectBLOB picture_image into :lb_image 
    from individual
    where individual_object_id='200506061121430020'
    using SQLCA;

    if SQLCA.sqlcode<>0 then
      messagebox("cannot connect","cannot connect")
    end if


    if(len(lb_image)>0) then


    ole_1.objectdata=lb_image


    gf_convertbmp(ole_1.objectdata,ls_path)


    end if

my gf_convertbmp следующим образом

    long          ll_index, ll_len, ll_length
    integer     li_FileNum

    // Find Keyword 'BM' for starting Bitmap File


     ll_len = Len(lb_ole_data)

     ll_index = 1 

     blob     lb_bm
     lb_bm = blob('BM')
     do while ll_index <= ll_len

       if BlobMid(lb_ole_data, ll_index, 2) = lb_bm then 

      exit
       end if   

        ll_index++;
     loop

     // Find Length of Image


      ll_length =  long(asc(char(BlobMid(lb_ole_data, ll_index - 4, 1)))) + &
                long(asc(char(BlobMid(lb_ole_data, ll_index - 3, 1)))) * 256 + &
                long(asc(char(BlobMid(lb_ole_data, ll_index - 2, 1)))) * 65536

       // Save Bitmap to File


      li_FileNum = FileOpen(filename, StreamMode!, Write!, LockWrite!, Replace!)


      // Write Bitmap Data


     do while ll_length > 0
          if ll_length > 32000 then
            FileWrite(li_FileNum, BlobMid(lb_ole_data, ll_index, 32000))
          else
            FileWrite(li_FileNum, BlobMid(lb_ole_data, ll_index, ll_length))
          exit
          end if
       ll_index += 32000
       ll_length -= 32000
      loop



      FileClose(li_FileNum)

1 Ответ

0 голосов
/ 30 мая 2012

Если это действительно растровое изображение в оболочке OLE, лучше всего (или, по крайней мере, тот, который я использую) открыть данные в виде olestream, а затем искать хранилище Ole10Native в потоке, который содержит данные.

// ls_storage is filename where data is written out
ll_rc = lole_storage.Open ( ls_storage )  

//Check to see that the Ole10Native storage exists.
ls_streamname = Char(1) + 'Ole10Native'
lole_storage.MemberExists ( ls_streamname, lb_objectexists )        
IF lb_objectexists THEN 
  //Start 4 bytes into the storage to get the file
  li_startat = 4            
ELSE
  Return -1
END IF  

ll_rc = lole_stream.Open( lole_storage, ls_streamname, stgRead!, stgExclusive! )

//Get the length of the OLE stream
ll_rc = lole_stream.Length ( ll_streamlen )


//Determine how many times to call Read
//read returns a maximum or 32765 characters at a time
//We are going to Seek to the first position, so don't include it in the
//calculations.  Also note that the Seek is zero-indexed, so we remove one
//from the startat for our calcs
ll_streamlen = ll_streamlen - ( li_startat - 1 )
IF ll_streamlen > ll_chunk THEN
    IF Mod( ll_streamlen, ll_chunk ) = 0 THEN
        ll_loops = ll_streamlen/ll_chunk
    ELSE
        ll_loops = ( ll_streamlen/ll_chunk ) + 1
    END IF
ELSE
    ll_loops = 1
END IF


//Read the OLE stream, starting at the requested position
ll_newpos = li_startat
FOR ll_i = 1 to ll_loops
    lole_stream.Seek ( ll_newpos )  
    ll_rc = lole_stream.Read( lblob_temp, ll_chunk )
    IF ll_i = 1 THEN
        ablb_dataout = lblob_temp
    ELSE
            ablb_dataout = ablb_dataout + lblob_temp
    END IF
    ll_newpos = ll_newpos + ll_chunk
NEXT

На данный момент у вас есть большой двоичный объект с растровыми данными

Однако данные, с которыми я работал, хранились в MS Paint. Недавно мы обнаружили, что более новые версии MS Paint хранят данные в формате WMF, а не BMP. В этом случае мы ищем хранилище OlePres000, а не хранилище Ole10Native, а затем запускаем в этом хранилище 40 символов, а не 4.

...