** [[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