** [[OOobbs3/7]] [#ge34bc34] -''サマリ'': Base 内のイメージデータを画像として取得したい -''環境'': Basic -''状態'': 解決 -''投稿者'': [[ike@九州]] -''投稿日'': 2010-06-12 (Sat) 11:50:28 *** 質問 [#w3af0f02] こんにちはお世話になります。 Base ではイメージをフォームを通して保存や表示をする事が出来ますが、そのイメージデータを画像としてクリップボードにコピーしたり又は Draw 等へ挿入するにはどのように扱ったら良いのでしょうか? 又、画像を Base に保存できるイメージデータとして取得するのも全く分かりません ギャラリでは出来ない色々なカテゴリ別での選別取得ができれば応用が広がりそうです。 宜しくお願いいたします。 *** 回答 [#re2713ea] - 色々やってなんだかうまくいかなかったのですが、python でローカルから読み込んだ bmp ファイルがクリップボード経由で貼り付けられました。OOo Basic でも試してみます。 -- はにゃ? &new{2010-06-12 (土) 18:10:18}; - とりあえず作成してみました。 &ref(ImageDB_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 #code(python){{ #! # -*- 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, }} -- はにゃ? &new{2010-06-12 (土) 20:20:54}; - 忘れていましたが、ベクトルタイプの画像はどうしますかねぇ・・・。 -- はにゃ? &new{2010-06-12 (土) 22:38:04}; - フォームコントロールの画像コントロールで右クリックして画像データを設定、フォームでデータを更新すると画像データは PNG 画像のデータとして保存されるようです。 BMP ファイルを入力したときに PNG になったので変だと思っていましたが、ベクトル系の EMF、WMF、SVM ファイルで試したところ全て PNG に変換されていました。 ついでに、PNG 画像から Writer にコピーペーストした画像を選択、コピーするとクリップボードのエントリーの種類に SVXB (StarView bitmap/animation) が含まれます。このデータを見ると独自ヘッダ+元データとなっているようです (BMP は独自ヘッダなし)。 とはいえこの SVXB はいつから使えるようになったんでしょう…。この形式もクリップボード経由の場合には使えるかもしれません。 -- はにゃ? &new{2010-06-13 (日) 01:57:51}; - 上記のフォームを使わずに画像をデータベースに入れるマクロを利用すると emf、svm ファイルを入れることができました。ですが ImageDB_1.odb フォームのコピーボタンを利用してコピーペーストするとラスター画像になってしまいます。形式によって変更すればよいのですが…。 -- はにゃ? &new{2010-06-13 (日) 02:53:28}; - 色々な試行有難うございました。全て確認できましたしマクロでの画像取り込みがベクトルタイプでも可なのは素晴らしいと思いました。コピーボタンではラスター画像になるのは残念ですが、非表示の draw に挿入 ".uno:cut" にてベクトルタイプでクリップボードへ貼り付ける事でもしのげそうなので取り敢えずやってみます。深謝です、夜遅くまで有難うございました。 -- ike@九州 &new{2010-06-13 (Sun) 11:19:43}; - もう少しいじったものを作成しました。&ref(ImageDB_2.odb); テーブルに画像の種類を保持するようにしました。また、画像の種類に応じてクリップボードの内容を変更します。ベクトル系の svm などもうまくいくと思います。 -- はにゃ? &new{2010-06-13 (日) 20:39:56}; - 試してみました。 Draw に貼り付けてみるとステータスバーに画像タイプが表示されるんですね。期待通りの動作でした…次のステップ、MySQL に接続設定した Base ファイルを解凍し サンプルファイル解凍からの SCRIPT フォルダをコピーして新たに同じテーブルを作成し MySQL 接続にても動作確認出来ました(フィールド追加しても OK )。 う~ん素晴らしい Base のカテゴリに目立つようにトピック作成される価値充分にありますよ これは。 -- ike@九州 &new{2010-06-14 (月) 11:34:33}; #comment *** 感想,コメント,メモ [#c83f3fff] #comment |