StretchBltについて

[戻る]
dd 2010/01/20(水) 09:08:46
いつもお世話になっています、ddです。

StretchBlt(...)を使っています。
今回表示するのは台形の図面ですが、
StretchBlt(...)不向きなので、

どうしたらいいでしょうか。
(図面の4点座標を使えるの関数があるのでしょうか)

よろしくお願いします。
環境:.Net2002 Windows XP

仲澤@失業者 2010/01/20(水) 09:22:26
質問は何ですか。資源の無駄なので
他人にわかるように質問してください。

dd 2010/01/20(水) 09:50:43
説明が不足ですが、すみません。
台形の図面というのは、図面が長方形ではなく
台形の形です。
要するに、
普段は長方形の図面を表示するのはStretchBlt(...)で十分です。
一点の座標+図面の幅+図面の長さで表示できますが、
台形の図面の場合、4点の座標が必要になります。
下辺の幅と上辺の幅が一致していないことです。
今回の質問が
上記の図面が4点座標を使って表示用の関数が探しています。
あるいは、他の方法があるのでしょうか。

>他人にわかるように質問してください。
StretchBlt(...)のパラメータが見ればわかります。

よろしくお願いします。

aetos 2010/01/20(水) 10:31:07
ご希望のものはありません。
GDI では基本的に矩形(長方形)なので、その台形を含む長方形を StretchBlt してく
ださい。

PATIO 2010/01/20(水) 10:34:45
良く分からないのですけれど、図面と言っているのは画像ファイルで
用意された物ですか?それともプログラム上でメモリDC等に描画したもの?

プログラムで画像を転送する場合、DC上にビットマップを選択して
転送先のDCに転送しますが、ビットマップは必ず矩形なので
転送関数も矩形で扱います。
ビットマップ上に載せた画像で意味がある部分が台形であっても
それは関係有りません。
従って意味が無い部分が転送先に影響を与えないように
マスク画像等を使って抜きを行うか、
透過色を設定して透過するかと言った事になると思います。

ですから、自分が扱っている画像が台形だからと言う考え方ではなく、
矩形の内の必要な部分を抜き出して転送するという考え方を
する必要があると思います。

もしくは転送先にリージョン等でマスクを掛けておくかなぁ。

画像転送関連でWEBを検索すれば、方法論は色々出てくると思います。

PATIO 2010/01/20(水) 10:40:43
あと、見ればわかると言うのは掲示板での質問ではどうかと思います。
文字だけのやり取りになりますので基本的に書かれた事が全てです。
あと、同じ物を見ても同じ解釈をするとは限りませんし、
見方は人それぞれなので自分の解釈を提示しないと話が噛み合わない
なんて事にもなりかねません。

掲示板でやり取りする場合は、基本的には詳しすぎるかなと思うくらい
説明してちょうど良いケースが多いのでなるべく詳しく説明するように
した方が良いと思います。
あと、詳しく説明しようとすると自分の考えとか見方を見直す機会になるので
結果的に問題点がわかって解決に結びつくこともありますよ。

たいちう 2010/01/20(水) 10:53:17
もしかして、こんなことがしたいんじゃないかと。
http://www.adobe.com/jp/support/kb/ts/224/ts_224567_ja-jp.html

仲澤@失業者 2010/01/20(水) 10:58:28
「図面」が何であるのかさっぱりわからないので外すかもしれませんが。

まず、「図面」がビットマップであると仮定すると、全てのビットマップは
長方形であって、全て長方形として処理する以外に手段はありません。

次に、「図面」が個々の座標を持つ点の集まりであると仮定した場合、
好きに描画できるので、何の問題もありません。

最後に「図面」が「図形(シェイプ)」であり、変形操作に対応できる
「台形」のデータの持ち方を検討しているなら、4点座標でなく、
平行な2直線関数とその他の2直線関数を持つのが演算が簡単です。
しかし、2つの平行線が常にX軸に平行であるなら、台形を包含する
長方形とその長方形の端点でない2点を持つものでも十分といえます。

ryo 2010/01/20(水) 12:41:39
元の画像から、台形部分だけを切り出して表示したいのか
元の画像を、台形に変形させて表示したいのか
元の絵が台形データで、それを、表示用の台形サイズにして表示させたいのか?
(こうなると、元の絵がどういうデータかさっぱりわからんが)

まだまだ色々想像つくがさっぱりわからん

とりあえず
>上記の図面が4点座標を使って表示用の関数が探しています。
無い

dd 2010/01/20(水) 14:53:13
皆さんの答えありがとう。

説明
1.図面=ラスターファイル、用意されたものです。
2.転送元が矩形であり、転送先が台形です。(描画の表示が台形です)
3.ファイル形式がTIFFです。
4.数十枚同じ台形画像を表示しています、画像同士が接合部分を一致しています。
(例:道路の線が繋がっています。)
5.図面の画像データが座標が持っています。
上辺の左右2点座標と下辺の左右2点座標があります、で、上辺の幅<下辺の幅。


確認
4  点座標を使って表示用の関数がない。

問題
>その台形を含む長方形を StretchBlt してください。
1.矩形で表示すると、上辺(幅小さい部分)伸びたんですが、
    延びた部分が座標に合わないです。
どう解決するなのか。

よろしくお願いします。

aetos 2010/01/20(水) 15:25:19
ひょっとして、座標変換しつつ表示したいってことなのかな?
矩形の画像を台形に歪めて表示したい。
道路の線という例があるけれど、ちょうど、長方形の地図をバードビューで見たよう
な。

PATIO 2010/01/20(水) 16:05:33
転送元が矩形で転送先が台形ならStretchBltじゃ無理ですね。
ただ、最初の質問の文書からこれを読み取れと言うのは無理ですね。

GDIにそういう変形を行なって画像を転送する関数はなかったような
気がします。私の知ってる範囲ではと言う話ですが。
知っている関数の範囲で何とかするとすると、
画素単位で座標変換して転送するくらいでしょうか。
めちゃくちゃ遅そうですけれど。

DirectXとかOpenGLにそういう転送をする関数があるかもと
思います。調べて見てはどうでしょう。

aetos 2010/01/20(水) 17:33:45
拡大、縮小、回転、平行移動、傾斜くらいなら SetWorldTransform でいけるんでしょう
けど、台形となるとわかりませんね。
# って、SetWorldTransform の使い方もよく知らないけど。

おんどり 2010/01/21(木) 03:24:32
転送関数を自分でつくれば簡単ですね。

subaru 2010/01/21(木) 12:51:49
使ったこと無いけどOpenCVでそのようなことができないでしょうか。

http://opencv.jp/sample/sampling_and_geometricaltransforms.html
ここの「画像の透視投影変換 cvGetPerspectiveTransform + cvWarpPerspective」の
例がそれっぽいかなと思えますけど。

dd 2010/01/25(月) 10:11:42
みなさんのご回答ありがとう。

確認したところ、完全台形ではないです、
変形が妥当だと思います、すみませんでした。
(上辺と下辺が平行ではないです。)
外形は矩形から矩形へ、
表示の内容が台形から変形へ。

やっぱり、アフィン変換になりますが。

>拡大、縮小、回転、平行移動、傾斜くらいなら SetWorldTransform でいけるんでしょう
見てみます。

>転送関数を自分でつくれば簡単ですね。
具体的のこと?


>使ったこと無いけどOpenCVでそのようなことができないでしょうか。
今は、MFC上でやっていますけど、
簡単に取り込みできるのでしょうか。(OpenCVをやったことがない)

よろしくお願いします。

仲澤@失業者 2010/01/25(月) 11:56:24
アフィン変換ほど簡単ではありませんね。
SDK/MFCのみでやるには、矩形から任意の四角形への変形関数を定義、
元画像のラスターのYに沿ってX方向に変形関数と、補間方法を適用して
転送先のビットカラーを演算し、転送先のDIBセクションのビットに代入
といった手続きになります。大変重い処理(Big Job)です。
一般に画像処理専用アプリ以外では必要のない処理ですので
設計の対象としているアプリケーションが、それらと関係ない場合は
「ビットマップの自由変形が必要となる」その仕様自体を
検討しなおしたほうが良いかもしれません。

PATIO 2010/01/25(月) 17:49:55
大変重い処理と言う部分に関しては同感です。

単純にアフィン変換を行っただけだと実際にはうまく行かないです。
例えばですが、縮小されるような方向の変換だと元の画像では
別々の画素である物が同じ場所にマッピングされるケースがありえます。
この場合、どのようにして転送先の画素を設定すれば、
元の画像が変形されたように見えるのかと言う問題があります。
単純に上書きをしているだけだと後勝ちになるので、望んだ画像になるとは
限りませんよね。

こういった画像処理に関しては単純に考えて処理を行っても
処理自体が重い、思ったような結果が得られないと言った状況に
なる事が多いと思います。画像処理のノウハウを既に持っている
技術者であればともかく、勉強しながらやっている状況だと
なかなか自分が望んだ結果を得るのは難しいでしょう。
それを実現できる画像処理ライブラリを使用する事で解決できれば
良いと思いますが、解決自体が困難であれば、
仕様自体を検討しなおした方が良いかもしれないと言う仲澤@失業者さんの
意見はごもっともだと思います。

おんどり 2010/01/25(月) 21:03:43
>>転送関数を自分でつくれば簡単ですね。
>具体的のこと?

ライブラリを使用することばかり考えずに、自分で画像転送処理を実装して
みてはいかがでしょう、という意味で書きましたが伝わらなかったようです。

今、手に入る本でしたら
[詳解]画像処理プログラミング SoftBank Creative
[改訂版]ディジタル画像処理の基礎と応用 CQ出版
などを参考にするのがお勧めです。

画像縮小アルゴリズムを一つ実装するだけでも結構楽しめます。

PATIO 2010/01/26(火) 11:41:19
> 画像縮小アルゴリズムを一つ実装するだけでも結構楽しめます。

御本人次第と言うところですね。
取り組む題材としては面白いと思います。
後はやる気と時間が取れるかという所でしょうか。

dd 2010/01/26(火) 12:02:07
みなさんのご回答ありがとう。

>「ビットマップの自由変形が必要となる」その仕様自体を
>検討しなおしたほうが良いかもしれません。

>仕様自体を検討しなおした方が良いかもしれないと言う仲澤@失業者さんの
>意見はごもっともだと思います。

そうですね、アフィン変換が簡単ではありません。
これから、アフィン変換が専用のソフトを使って変換してもらいます。
変換後のラスタデータを貼り付けます。
その余白部分を隠して表示します。

>従って意味が無い部分が転送先に影響を与えないように
>マスク画像等を使って抜きを行うか、
>透過色を設定して透過するかと言った事になると思います。

これから、この技法をやってみます。(やったことがない)

>[詳解]画像処理プログラミング SoftBank Creative
>[改訂版]ディジタル画像処理の基礎と応用 CQ出版
>などを参考にするのがお勧めです。
今度休みの日、見てみます。
ありがとうございます。

皆さん、いろいろ教えていただく、ありがとうございました。

ロマ 2010/01/26(火) 20:56:32
アフィン変換はPlgBltを使えば簡単にできます。
元の図が長方形だとすると変換後は平行四辺形になります。
例)
 元の図上のどのような平行線も変換後は平行のままです
 元の図の上辺近くの部分と下辺近くの部分も同じ変形をうけます

ddさんが望むのがこのようなものであり、
変換先を台形にクリップしたいだけならば、
変換先のhdcにSelectClipRgnなどを使えばできます。

そうではなく、長方形の図を斜め下から見たような、
つまり、下辺に比べ、上辺が圧縮されたような変形を望むのでしたら、
これは、アフィン変換ではありません。
DirectXなど、3Dライブラリでやるのが簡単だと思います。

dd 2010/01/28(木) 12:28:50
ロマ さん
ご回答ありがとう。

>アフィン変換はPlgBltを使えば簡単にできます。
>元の図が長方形だとすると変換後は平行四辺形になります。
元図面が上下辺が平行していますが、変換後平行ではないです。

>DirectXなど、3Dライブラリでやるのが簡単だと思います。
適当なサンプルがありますか、
興味があります。(やったことがありません)

よろしくお願いします。

ロマ 2010/01/28(木) 20:41:52
お力になれず、申し訳ありません。

dd 2010/01/29(金) 08:32:49
[[解決]]
いろいろ案がありますが、
1.画像転送処理
2.OpenCV 
3.DirectXなど、3Dライブラリ
>下辺に比べ、上辺が圧縮されたような変形を望むのでしたら、
そうではないです、やっぱり、DirectXが無理でしょうね
4.OpenGL

いずれも時間がかかりそうですが、
検討してからやってみます。

皆さんご回答ありがとうございました。

bun 2010/01/29(金) 13:06:56
今さらですが、
DIBを使えば比較的簡単にできそうな気がします。

DIBについては、こちらが詳しいです。
http://eternalwindows.jp/graphics/bitmap/bitmap00.html
要は、DIBを使うと画像をドット配列として扱うことができるのです。

その上でこちらを参照してください。
http://homepage2.nifty.com/tsugu/sotuken/rotation/
これは画像回転の例ですが、
[回転処理の基本]に書かれているように、出力画像の座標から入力画像の座標を
計算してやれば、回転に限らず、拡大縮小も自由自在です。
台形画像なら、上と下で拡大率(縮小率)が違うだけのことです。

拡大率(縮小率)によっては、出力画像の座標と入力画像の座標が1対1になりま
せんのでエッジが目立ったり、不自然な色になったりします。
それを補正するのが、ホームページに書かれている線形補間です。

ホームページには高速化手順も書かれていますが、
回転変形と違って、台形変形なら、処理速度は大して問題にならないはずなので
とにかくチャレンジしてみてはどうでしょう。

dd 2010/02/01(月) 15:52:33
bunさん
情報ありがとう。
これから、画像転送の処理をやってみます。

ありがとうございました。

古いスレッドには追加発言できません。