Top > OOobbs3 > 7

OOobbs3/7 Edit

  • サマリ: Base 内のイメージデータを画像として取得したい
  • 環境: Basic
  • 状態: 解決
  • 投稿者: ike@九州?
  • 投稿日: 2010-06-12 (Sat) 11:50:28

質問 Edit

こんにちはお世話になります。

Base ではイメージをフォームを通して保存や表示をする事が出来ますが、そのイメージデータを画像としてクリップボードにコピーしたり又は Draw 等へ挿入するにはどのように扱ったら良いのでしょうか?

又、画像を Base に保存できるイメージデータとして取得するのも全く分かりません

ギャラリでは出来ない色々なカテゴリ別での選別取得ができれば応用が広がりそうです。

宜しくお願いいたします。

回答 Edit

  • 色々やってなんだかうまくいかなかったのですが、python でローカルから読み込んだ bmp ファイルがクリップボード経由で貼り付けられました。OOo Basic でも試してみます。 -- はにゃ? 2010-06-12 (土) 18:10:18
  • とりあえず作成してみました。 fileImageDB_1.odb

データベースに入れた画像をフォーム上のコピーボタンでクリップボードにコピーします。 Python で書いたマクロをデータベースドキュメントに入れると「サポートしていません」と出たので、OOo Basic を経由して呼び出しています。

Draw などに挿入するときはドキュメント辺りに XTransferable を突っ込めばいいかと。

データベースのカラムを LONGVARBINARY などにすると保持されるデータはバイナリになります。このとき画像データは setBinaryStream メソッドで css.io.XInputStream を与えるとよさそうです。

Sub PutImageIntoDatabase
 oDoc = ThisComponent
 oForm = oDoc.getDrawPage().getForms().getByIndex(0)
 
 If IsNull(oForm.ActiveConnection) Then
   oForm.execute()
   If oForm.isBeforeFirst() Then oForm.first()
 End If
 
 nIDID = oForm.findColumn("ID")
 nNameID = oForm.findColumn("NAME")
 nImageID = oForm.findColumn("IMAGE")
 
 sImageURL = "file:///home/user/Documents/images/w.png"
 
 sfa = CreateUnoService("com.sun.star.ucb.SimpleFileAccess")
 io = sfa.openFileRead(sImageURL)
 nSize = sfa.getSize(sImageURL
 
 ' goto new row
 oForm.moveToInsertRow()
 
 ' update row data
 oForm.updateInt(nIDID, oForm.RowCount)
 oForm.updateString(nNameID, "w")
 oForm.updateBinaryStream(nImageID, io, nSize)
 oForm.insertRow() 
End Sub

画像をデータベースに入れるよりもパスを入れておいてそこを参照の方がいい気がしますけど。

Python で書いた部分は以下。これをフォームのボタンに割り当てた CopyButton_Pushed から呼び出しています。

' copy data to clipboard button pushed
Sub CopyButton_Pushed(ev)
 sMacroPath = "ImageDB.py$copy_pushed"
 CallPythonMacroWithEvent(ThisDatabaseDocument, sMacroPath, ev)
End Sub


Sub CallPythonMacroWithEvent(oDoc As Object, sPart As String, ev As Object)
 sURI = "vnd.sun.star.script:" & sPart & "?language=Python&location=document"
 oSP = oDoc.getScriptProvider()
 oScript = oSP.getScript(sURI)
 If NOT IsNull(oScript) Then
   oScript.invoke(Array(ev), Array(), Array())
 End If
End Sub
  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
#!
# -*- coding: utf-8 -*-
 
import uno
import unohelper
 
from com.sun.star.datatransfer import XTransferable, DataFlavor
from com.sun.star.beans import PropertyValue
 
"""Images into the database as binary data."""
 
# database columns
ID_Name = 'ID'             # INTEGER
NAME_Name = 'NAME'         # VARCHAR
IMAGE_Name = 'IMAGE'     # LONGVARBINARY
 
 
def copy_pushed(ev):
    """copy the image, when copy button is pushed."""
    form = ev.Source.getModel().getParent()
    if not form:
        print('no form.')
        return
    
    # get image data from rowset of the form
    imageID = form.findColumn(IMAGE_Name)
    stream = form.getBinaryStream(imageID)
    
    ctx = XSCRIPTCONTEXT.getComponentContext()
    smgr = ctx.getServiceManager()
    
    # convert graphic to bitmap
    args = []
    args.append(make_PropertyValue('InputStream', stream))
    
    gp = smgr.createInstanceWithContext(
        'com.sun.star.graphic.GraphicProvider', ctx)
    g = gp.queryGraphic(tuple(args))
    if not g:
        print('null graphic.')
        return
    data = g.getDIB()
    
    if not data:
        print('empty data')
        return
    try:
        set_bmp_to_clipboard(ctx, data)
    except Exception as e:
        print(e)
 
 
class DataTransferable(unohelper.Base, XTransferable, object):
    """Keep clipboard data and provide them."""
    
    MimeType = ''
    HumanPresentableName = ''
    
    def __init__(self, data):
        df = DataFlavor()
        df.MimeType = self.MimeType
        df.HumanPresentableName = self.HumanPresentableName
        self.flavors = [df]
        self.data = [data]
    
    def getTransferData(self, flavor):
        if not flavor: return
        mtype = flavor.MimeType
        for i, f in enumerate(self.flavors):
            if mtype == f.MimeType:
                return self.data[i]
    
    def getTransferDataFlavors(self):
        return tuple(self.flavors)
    
    def isDataFlavorSupported(self, flavor):
        if not flavor: return False
        mtype = flavor.MimeType
        for f in self.flavors:
            if mtype == f.MimeType:
                return True
        return False
 
 
class BmpDataTransferable(DataTransferable):
    """transferable for bitmap data."""
    MimeType = 'image/bmp'
    HumanPresentableName = 'Bitmap' 
    
    def __init__(self, data):
        DataTransferable.__init__(self, data)
 
 
def set_bmp_to_clipboard(ctx, data):
    t = BmpDataTransferable(data)
    
    cl = ctx.getServiceManager().createInstanceWithContext(
        'com.sun.star.datatransfer.clipboard.SystemClipboard', ctx)
    if not cl: return
    cl.setContents(t, None)
 
 
def make_PropertyValue(name, value):
    p = PropertyValue()
    p.Name = name
    p.Value = value
    return p
 
 
g_exportedScripts = copy_pushed,
  • はにゃ? 2010-06-12 (土) 20:20:54
  • 忘れていましたが、ベクトルタイプの画像はどうしますかねぇ・・・。 -- はにゃ? 2010-06-12 (土) 22:38:04
  • フォームコントロールの画像コントロールで右クリックして画像データを設定、フォームでデータを更新すると画像データは PNG 画像のデータとして保存されるようです。 BMP ファイルを入力したときに PNG になったので変だと思っていましたが、ベクトル系の EMF、WMF、SVM ファイルで試したところ全て PNG に変換されていました。

ついでに、PNG 画像から Writer にコピーペーストした画像を選択、コピーするとクリップボードのエントリーの種類に SVXB (StarView bitmap/animation) が含まれます。このデータを見ると独自ヘッダ+元データとなっているようです (BMP は独自ヘッダなし)。 とはいえこの SVXB はいつから使えるようになったんでしょう…。この形式もクリップボード経由の場合には使えるかもしれません。

  • はにゃ? 2010-06-13 (日) 01:57:51
  • 上記のフォームを使わずに画像をデータベースに入れるマクロを利用すると emf、svm ファイルを入れることができました。ですが ImageDB_1.odb フォームのコピーボタンを利用してコピーペーストするとラスター画像になってしまいます。形式によって変更すればよいのですが…。 -- はにゃ? 2010-06-13 (日) 02:53:28
  • 色々な試行有難うございました。全て確認できましたしマクロでの画像取り込みがベクトルタイプでも可なのは素晴らしいと思いました。コピーボタンではラスター画像になるのは残念ですが、非表示の draw に挿入 ".uno:cut" にてベクトルタイプでクリップボードへ貼り付ける事でもしのげそうなので取り敢えずやってみます。深謝です、夜遅くまで有難うございました。 -- ike@九州 2010-06-13 (Sun) 11:19:43
  • もう少しいじったものを作成しました。fileImageDB_2.odb

テーブルに画像の種類を保持するようにしました。また、画像の種類に応じてクリップボードの内容を変更します。ベクトル系の svm などもうまくいくと思います。

  • はにゃ? 2010-06-13 (日) 20:39:56
  • 試してみました。 Draw に貼り付けてみるとステータスバーに画像タイプが表示されるんですね。期待通りの動作でした…次のステップ、MySQL に接続設定した Base ファイルを解凍し サンプルファイル解凍からの SCRIPT フォルダをコピーして新たに同じテーブルを作成し MySQL 接続にても動作確認出来ました(フィールド追加しても OK )。 う~ん素晴らしい Base のカテゴリに目立つようにトピック作成される価値充分にありますよ これは。 -- ike@九州 2010-06-14 (月) 11:34:33

感想,コメント,メモ Edit



Attach file: fileImageDB_2.odb 1369 download [Information] fileImageDB_1.odb 1428 download [Information]

Reload   New Lower page making Edit Freeze Diff Upload Copy Rename   Front page List of pages Search Recent changes Backup   Help   RSS of recent changes