DOBON.NET DOBON.NETプログラミング掲示板過去ログ

画像の一部消去? 雛形について

環境/言語:[環境(Windows2000, XP)、使用言語( C#.NET)]
分類:[.NET]

C#、画像処理共に初めての開発で拙い質問で申し訳ないのですが、よろしくおねがいいたします。

動的に画像を配置し、JPGファイルを保存するプログラムを書きたいと思っております。

同じようなJPGファイルを複数作成するのですが、
ある一定までは共通の表示(雛形)で、一部の画像を書き換えてJPGファイルを保存していきたいのです。

ライブラリを見たところ、
Graphics.Save と
Graphics.Restore で
一部の書き換えが可能かと思い試したのですが、うまくいきませんでした。
どうしたかというと、

メンバに以下を宣言
Graphics    g;
GraphicsState gs;

クラスのコンストラクタで
bmp = new Bitmap( PictureBox1.Width, PictureBox1.Height );
g = Graphics.FromImage(bmp);
g.DrawLine(略);
g.DrawString(略);
など、ある一定の部分までを作成し、
gs = g.Save();

とし、
書き換える繰り返し処理上で
for((略))
{
    if( gs != null)
    {
        //ここで"一部"の部分を消して共通表示の部分のみにしたい
        g.Restore( gs );
    }

    //一部の処理
    g.DrawImage(略);
    bmp.Save(略);//JPGファイルを作成
}

と書いたのですが、
できたJPGファイルには、
前回のループ上の"一部の処理"が残ってしまい、
Restoreメソッドのライブラリにある記述のように
「Save メソッド呼び出し時の状態に復元」されませんでした。

間違いを指摘していただきたいと思います。
他のやり方があるのでしょうか。

よろしくお願いいたします。
> 間違いを指摘していただきたいと思います。

Graphics.Save(), Graphics.Restore() の仕様を勘違いしています。

Graphics.Save(), Graphics.Restore() によって保存・復帰されるのは「Graphics オブジェクトの状態」であって、「Graphics に選択されているビットマップ」は含まれていません。
■No10718に返信(渋木宏明(ひどり)さんの記事)
> Graphics.Save(), Graphics.Restore() によって保存・復帰されるのは「Graphics オブジェクトの状態」であって、「Graphics に選択されているビットマップ」は含まれていません。
>

まだまだ理解が足りないようです。
ご教授どうもありがとうございました!

他のやり方を模索することに致します。


何か良い方法をご存知の方、ご教授ください。
どうぞよろしくお願いいたします。
> 他のやり方を模索することに致します。
> 何か良い方法をご存知の方、ご教授ください。

#「模索する」と言った傍から人に訊ねるのは何か違うと思うのは私だけかしら :-p


 単純に、『雛形となる Bitmap オブジェクト』と『一部書き換えて保存するための Bitmap オブジェクト』とを別のものにするというのでは不味いのでしょうか?
■No10729に返信(深山さんの記事)
> #「模索する」と言った傍から人に訊ねるのは何か違うと思うのは私だけかしら :-p
>
>  単純に、『雛形となる Bitmap オブジェクト』と『一部書き換えて保存するための Bitmap オブジェクト』とを別のものにするというのでは不味いのでしょうか?
>
回答有難うございました。
私なりに考えていたのですが、なかなか思いつかず
より早く良いアイディアがあるといいなと思い、
返信を書く際に聞いてしまいました。すみません。

一部書き換え個所に
BitmapImageを複数配置しているのですが、(最初の質問のg.DrawImageの個所です)
躓いている個所があります。
「Bitmapの削除」が出来ないのです。

RemovePropertyItemを使用するのだと思い、以下のようなコードを書きました。
( 参考:http://msdn2.microsoft.com/library/ahafhz84(en-us,vs.80).aspx )

------------------------------
Bitmap bitmapImage;

// FileStream を開く
hStream = new FileStream(@sFileName, System.IO.FileMode.Open);
// FileStream から画像を読み込んで表示
bitmapImage = (Bitmap)Image.FromStream(hStream);
hStream.Close();

//プロパティ値取得
PropertyItem[] propItems;
propItems = bitmapImage.PropertyItems;

//削除
foreach( PropertyItem propItem in propItems )
{
bmpRmv.RemovePropertyItem( propItem.Id );
}
------------------------------
上記の記述ですと、プロパティ値取得 で、Length=0となり、
foreach文で例外が発生します。

bitmapImageには画像は取得されているのですが、
何か処理が足りないのでしょうか。
よろしくお願いいたします。


あと、一部書き換え個所には文字列もあり、
上記のg.DrawImageと同様にg.DrawStringで書いているのですが、
この削除についてもBitmapを使用する?のでしょうか。
よく解っていないのでおかしな質問をしていたらすみません。

よろしくお願いいたします。
> 私なりに考えていたのですが、なかなか思いつかず
> より早く良いアイディアがあるといいなと思い、
> 返信を書く際に聞いてしまいました。すみません。

 いえいえ、これから気を付けて頂ければ良いのです♪ ‥‥って、なんか偉そうですね、私(^_^;)
#こんなこと書いてるから[悪い]に票を入れられるんだろうなぁ。

 偉そう序でなのでもう一つ。

書き込みのマナーについて
http://dobon.net/vb/bbs/index.html

にもあるように、質問は一つのスレッドの中で一つにするようにしましょう。
 関連する内容を続けてというのも場合によってはありでしょうけど、一つ目が解決していないうちに別のものを提示してしまうと話の焦点がぼやけてしまいますし、スレッドの見通しも悪くなってしまいますから。
#それにあれもこれもとやってると却って混乱しません?


 で、今回お訊ねになられてる内容は当初の質問とはまったく別のもののように感じるのですけれど‥‥
>> 単純に、『雛形となる Bitmap オブジェクト』と『一部書き換えて保存するための Bitmap オブジェクト』とを別のものにするというのでは不味いのでしょうか?
は用をなしたのでしょうか? なさなかったのでしょうか?
 なしたのであればどのようにされたのか、なさなかったのであればどこに問題があったのか、ご報告頂ければ幸いです。
#いや、↓の内容からするとお役には立てなかったのでしょうけど。
> 上記のg.DrawImageと同様にg.DrawStringで書いているのですが、
> この削除についてもBitmapを使用する?のでしょうか。


> BitmapImageを複数配置しているのですが、(最初の質問のg.DrawImageの個所です)
> 躓いている個所があります。
> 「Bitmapの削除」が出来ないのです。

 突然『削除』と仰られても話が見えません(汗)<先のコードにも今回のものにもそのような箇所はありませんし、 DrawImage と削除がどう関わるのかの説明もありませんので。

> RemovePropertyItemを使用するのだと思い、以下のようなコードを書きました。

 何故そのように判断なさったのかも不明ですけど‥‥ FileStream から Bitmap を作成しているようですので、次の内容が参考になるかも知れません。
#「Bitmapの削除」を『ファイルの削除』と解釈しました。別の意味合いで書かれたのでしたら流してくださいませ。

BITMAP.Clone()について
http://dobon.net/vb/bbs/log3-14/8405.html
■No10736に返信(深山さんの記事)

一貫して当初の質問の続きのつもりだったのですが、
手探り状態で色々試していての書き込みだったので、違う質問に見えてしまいすみません。
確かに読み返してみると違うものにみえます。
より詳しく書こうとしたのですが、裏目に出てしまいました。
しかも説明不足で違う質問をしているように見えます。

ファイルの削除は問題としておりません。分かりにくい質問をしてしまいすみません。

お教えいただいたBITMAP.Clone()は、複製の作成のようなので、また今度の機会に参考にさせていただきたいと思います。
ありがとうございました。

改めて、補足説明をさせていただきます。
表示したBitmapの削除が出来ずこまっております。
書き換え用の箇所にg.DrawImage()関数にてBitmapファイルを表示したのですが、
次のFOR文のループの回には別のBitmapファイルをg.DrawImage()関数にて表示したいので、
BitmapをJPGファイルに出力した後、g.DrawImage()で表示した画像の箇所のみを削除したいと考えて、
前回のRemovePropertyItem関数に行き着いたのですが、前回の方法でうまくいかず、行き詰っています。

どうぞよろしくお願いいたします。
> g.DrawImage()で表示した画像の箇所のみを削除したいと考えて、

だから、そんなこと出来ませんて。

既出ですが、好き勝手に「描いてから消す」んじゃなくて、「書き込む前のビットマップを複製しておく」ばいいんじゃないですか?
#既に渋木さんからのレスが付いるので不要だろうと思いつつも、下書きしてたのを捨てられずにカキコ

> 手探り状態で色々試していての書き込みだったので、違う質問に見えてしまいすみません。

 こちらこそ、読解力が不足していたようで申し訳ありませんm(__)m


> 表示したBitmapの削除が出来ずこまっております。

 しつこいようですが‥‥
 復元/削除に拘るのは何故なのでしょうか?

 kyoroさんがなさりたいと仰ってるのは次のようなイメージだと捕えておりました。

  1. □を描画する
  2. ○を描画する
  3. □○が描かれているものをファイルに保存する
  4. ○を消して 1 の状態に戻す
  5. △を描画する
  6. □△が描かれているものをファイルに保存する
  7. △を消して 1 の状態に戻す
    :
    :

 そこで先のような提案をさせて頂きました。上述に合わせると次のようなイメージです。
#描画したものを戻すという機能が標準で用意されているとは思えなかったので。勿論、私が無知なだけという可能性は多分にあります。

  1. □を描画する
  2. 1 を元に□の描かれているものをもう一つ作る
  3. 2 で作成したものに○を描画する
  4. □○が描かれているものをファイルに保存する
  5. 1 を元に□の描かれているものをもう一つ作る
  6. 5 で作成したものに△を描画する
  7. □△が描かれているものをファイルに保存する
    :
    :

 しかしながらこの方法では問題があった様子。その理由を訊ねてもお答え頂けませんでしたし‥‥それともそもそも私が大きな誤解をしているのでしょうか?


> 前回のRemovePropertyItem関数に行き着いたのですが、前回の方法でうまくいかず、行き詰っています。

 少しだけしか調べてませんが、 PropertyItem はkyoroさんがお考えになっているものとは異なる印象を受けました。どのような経緯でそこに辿り着いたのでしょうか?
#メタデータを削除なさりたいわけではないのですよね? PropertyItems の Length が 0 になっているということは、そのイメージがメタデータを含んでいないということだと思うのですけど。
■No10744に返信(深山さんの記事)

>  少しだけしか調べてませんが、 PropertyItem はkyoroさんがお考えになっているものとは異なる印象を受けました。どのような経緯でそこに辿り着いたのでしょうか?
> #メタデータを削除なさりたいわけではないのですよね? PropertyItems の Length が 0 になっているということは、そのイメージがメタデータを含んでいないということだと思うのですけど。

はい。おっしゃられるとおりです。
BitmapのMSDNライブラリを見ていて使用できると(勘違いですが)考えたのですが、
私も何度も解説を読んでいるうちにやっと気づきました・・。
ファイル種類や、基礎についてもっと勉強する必要があります。

早速のレス有難うございました。

"沢山newするのは良くない"とのことを言われていて、
なんとか1つのbmp上で作業をしようと、消すことに躍起になっておりました。

しかし、見当違いだったようです。
こちらこそ読解力が無く、混乱してしまい申し訳ありません。
前回レスを書いてから気づいたのですが、フォロを入れる時間がありませんでした。
遅いレスですみません。

大変解りやすい解説有難うございました。


Removeも使えないようですので、お教えいただいた方法でやって見ようと思います。

長い間親切にご教授くださり、感謝いたしております。有難うございました!
■No10745に返信(kyoroさんの記事)

すみません。 解決済み!チェック入れ忘れましたので
追記です・・。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板