画像を加工処理する機能について

タグの編集
投稿者 hori  (社会人) 投稿日時 2009/10/28 17:48:42
これはマルチポストになるかもしれませんが、ぜひ管理人のるきおさんにお尋ねしたいと思い
投稿しました。
VB2008でこちらの講座でも学ばせていただきました。

本題にはいりますが、小生、オリジナルの年賀状作成ソフトを作ってみようと思って取り組んでいます。
その中で、ワードやエクセル、一太郎などのソフトで画像を取り込んだときに、選択枠ができ
その4隅にマウスを持って行くと拡大、縮小ができるような機能を実装しようと思いました。
しかし、どの書籍やサイトをみても、この機能についての説明などは掲載されておりません。
(調べ方が十分ではないのかもしれませんが)


こうした機能を実装することは、まだ初級者レベルでは敷居が高いのでしょうか?

(グラフィックソフトにも同じような機能は付属しているので、ライブラリとして存在しているものと
思いこんでいたのですが、今のところはないのですね。)
よろしくお願いします。
投稿者   (社会人) 投稿日時 2009/10/28 18:40:08
> これはマルチポストになるかもしれませんが
マルチポストしてるのですか?
(用語勘違いしてませんか?)

> ぜひ管理人のるきおさんにお尋ねしたいと思い投稿しました。

るきおさん限定で回答が欲しいと?
他の人が知ってても回答しちゃダメと?
投稿者 るきお  (社会人) 投稿日時 2009/10/28 21:34:32
こんにちは。
私であれ他の方であれ名指しで回答を要望することは今後しないようにお願いします。

たくさんの知識・経験がある方々にもこの掲示板で発言していただいており、
そのようなアドバイスをもらう機会を少なくすることはhoriさんにとっても損だと思います。

今回の件

>こうした機能を実装することは、まだ初級者レベルでは敷居が高いのでしょうか?
はい。そう思います。

>(グラフィックソフトにも同じような機能は付属しているので、ライブラリとして存在しているものと
>思いこんでいたのですが、今のところはないのですね。)
VB標準(.NET標準)ではなかったと思います。
市販のものやフリーウェア・シェアウェア等調べればあるかもしれません。


PictureBoxの右端のサイズだけ変えられるサンプルを作ってみましたので参考にしてください。
    
Public Class Form1

    Private IsSizable As Boolean    'サイズ変更可能状態か? 
    Private IsSizing As Boolean     'サイズ変更中か? 

    Private Sub PictureBox1_MouseDown(ByVal sender As ObjectByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown

        'サイズ変更可能状態でマウスを押下した場合、サイズ変更中にする。 
        If IsSizable Then
            IsSizing = True
        End If

    End Sub

    Private Sub PictureBox1_MouseLeave(ByVal sender As ObjectByVal e As System.EventArgs) Handles PictureBox1.MouseLeave

        'マウスがPictureBox外に出たときはカーソルを通常にして、フラグをすべてリセットする。 
        Me.Cursor = Cursors.Default
        IsSizable = False
        IsSizing = False

    End Sub

    Private Sub PictureBox1_MouseMove(ByVal sender As System.ObjectByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove

        If IsSizing Then
            'サイズ変更中ならサイズを変更する 
            PictureBox1.Width = e.X
        Else
            'サイズ変更中でないならサイズ変更可能状態か判断しマウスの形状を変更する。 
            ArrowMouse(sender, e.X, e.Y)
        End If

    End Sub

    ''' <summary> 
    ''' サイズ変更可能状態か判断し、必要に応じてマウスの形状を変更する。 
    ''' MouseLeaveイベントでもマウスの状態を変更しているのに留意のこと。 
    ''' </summary> 
    Private Sub ArrowMouse(ByVal cnt As Control, ByVal x As IntegerByVal y As Integer)

        If x >= (cnt.Width - 5) Then
            'コントロールの右端から内側に5ピクセル内にマウスがあるときサイズ変更可能 
            Me.Cursor = Cursors.SizeWE
            IsSizable = True
        Else
            'それ以外のときサイズ変更不可。 
            Me.Cursor = Cursors.Default
            IsSizable = False
        End If

    End Sub

    Private Sub PictureBox1_MouseUp(ByVal sender As ObjectByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp

        IsSizing = False

    End Sub

    Private Sub Form1_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load

        PictureBox1.Image = Image.FromFile("C:\windows\winnt.bmp")
        PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage

    End Sub
End Class



まだまだいろいろ改造する必要がありますが、たたき台として使用できるレベルと思います。
これをカスタムコントロールにでもすれば将来楽だと思います。
投稿者 るしぇ  (社会人) 投稿日時 2009/10/29 01:53:29
不安ならマルチポストとして対応しておけばいいだけでは?
http://hpcgi1.nifty.com/MADIA/vbnet/wwwlng.cgi?print+200910/09100019.txt

> 私であれ他の方であれ名指しで回答を要望することは今後しないようにお願いします。
そんなこと言ったところで回答つけるなら同じだと思います。
上手くいくから実行するのだと思います。
自分が必要な情報だけ欲しいと思うのも当然の行動かと思います。
今後も、他の回答者がスルーするかどうか程度の違いしか出ないでしょう。
投稿者 hori  (社会人) 投稿日時 2009/10/29 02:38:25
>私であれ他の方であれ名指しで回答を要望することは今後しないようにお願いします

すみません。私としては信頼のおける、るきおさんから指導を受けたかったものですから
(他の回答者の方すべてが信頼できないとは言ってないので誤解のないように)
今後るきおさんから直接のご指導を仰ぎたいときはメールでよろしいのでしょうか
もちろん、迷惑がかからないように過度のメールは慎みますが


サンプルまで作っていただき有り難うございます。参考にさせていただきます。
投稿者 まだまだ  (中学生) 投稿日時 2009/10/29 03:21:32
>今後るきおさんから直接のご指導を仰ぎたいときはメールでよろしいのでしょうか
もちろん、迷惑がかからないように過度のメールは慎みますが

http://homepage1.nifty.com/rucio/main/material/m.htm
ここに書いてありますよ。
投稿者 hori  (社会人) 投稿日時 2009/10/29 03:24:29
>ここに書いてありますよ。 
 了解しました。ありがとう
 

投稿者 cupid  (社会人) 投稿日時 2009/10/29 09:02:34
画像の拡大縮小は何かと面倒ですよ。
グラフィックだのPictureBoxだのあるいはBmp構造体だの、知識レベルに応じて説明を変えるのも面倒だし。見た目にサイズ変えるだけなら、PictureBoxの幅と高さを変えれば済むけど、見た目は汚くなる。さらに、マウス操作に連動させるとなると、それも面倒。
Bmp構造体なんて考えずに拡縮しようとするるとき、ペイントするのが簡単に綺麗にできる方法。ペイントしたグラフィックをPictureBoxに貼り付けるのだったか。しかし、マウス操作に連動というわけには行かない。
ここに書き込むのは質問者さんに答える為だけでなく、発露したい為でもあるから、メールで個人的やり取りなんて迷惑千番、多分そうだと思いますよ。
投稿者 hori  (社会人) 投稿日時 2009/10/29 15:57:39
画像関係のプログラムを作成している人はあまりいないように感じていましたが、グラフィック関連特有の面倒さもあるのですね。
年賀状ソフトなど、フリーソフトでいくらでころがっているのにあえて作る必要もないのですが、
その中にある機能の実現方法を知りたくて取り組んでみましたが、早々に行く詰まってしまい、今回質問した次第です。
それにしても書籍を人とおり学んでもスムーズに作成できるものではないのですね。
それこそMSDNを片っ端から読み込んでいなければ、とても満足なものはつくれないと感じました。
(簡単なものは、作れますが中級レベル以上のものになるともう手も足もでなくなるのが現実です)
先は長いですね。
投稿者 daive  (社会人) 投稿日時 2009/10/29 16:54:01
Freeのペイントソフト系で、有名なのは、
GIMP(ソースコード公開)
GIMP2(ソースコード公開)
PAINT.NET(過去にはソース公開、現在は見当たらない)
あたりでしょうか、
CADでは、GWCAD

もう一つの掲示板にも書かれていましたが、
ラバーバンド
アンカーポイント
ラスターグラフィック(@ITだったか、CodeZineだったかに、簡易な記事があります。)
=ベクターグラフィク(ベクトルグラフィック)
ビットマップグラフィック(@ITだったか、CodeZineだったかに、簡易な記事があります。)

Windowsでは、GDI/GDI+系の機能を使ったりして
作成することになります。
Direct-Xも考えられます。
投稿者 hori  (社会人) 投稿日時 2009/10/29 18:26:19
情報有り難うございます。
投稿者 hori  (社会人) 投稿日時 2009/12/3 18:10:09
るきおさんにおしえてもらったのを若干手を加えたのですが、(といってもほとんどおなじかもしれません)どうしても理解できない部分があるのでご教授願います。

画像を読み込んで、その画像を拡大、縮小、及び移動はできますが、画像を最大に拡大してしまった
ときに、マウスの形状が変化しなくなってしまいます。
また、他の画像を読み込んだときに、それ以前に読み込まれていた画像と同じサイズになってしまいます
(これは初期化が必要なのだと思いますが、)





 Private IsSizable As Boolean    'サイズ変更可能状態か? 
    Private IsSizing As Boolean     'サイズ変更中か? 

    Dim sx As Integer, sy As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        OpenFileDialog1.Filter = "jpeg(*.jpg,*.jpg)|*.jpg;*.jpg|" + "   ビットマップ(*.bmp)|*.bmp"


        Dim fname As String = ""
        OpenFileDialog1.Filter = "jpeg(*.jpg,*.jpg)|*.jpg;*.jpg|" + "   ビットマップ(*.bmp)|*.bmp"
        'ファイルを開くダイアログボックス
        If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then

            'ファイル名を取得
            fname = OpenFileDialog1.FileName
            '読み込み
            PictureBox1.Image = Image.FromFile(fname)
        End If
      

    End Sub

    Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        sx = e.X
        sy = e.Y
        'サイズ変更可能状態でマウスを押下した場合、サイズ変更中にする。 
        If IsSizable Then
            IsSizing = True
        End If
    End Sub

    Private Sub PictureBox1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseLeave

        'マウスがPictureBox外に出たときはカーソルを通常にして、フラグをすべてリセットする。 
        Me.Cursor = Cursors.Default
        IsSizable = False
        IsSizing = False

    End Sub


  
    Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
       
        If IsSizing Then
            'サイズ変更中ならサイズを変更する 
            PictureBox1.Width = e.X
           
        Else
            'サイズ変更中でないならサイズ変更可能状態か判断しマウスの形状を変更する。 
            ArrowMouse(sender, e.X, e.Y)
            If e.Button = Windows.Forms.MouseButtons.Left Then
                Dim mx As Integer = PictureBox1.Left + e.X - sx
                Dim my As Integer = PictureBox1.Top + e.Y - sy
                PictureBox1.Location = New Point(mx, my)
            End If
        End If
    End Sub

    ''' <summary> 
    ''' サイズ変更可能状態か判断し、必要に応じてマウスの形状を変更する。 
    ''' MouseLeaveイベントでもマウスの状態を変更しているのに留意のこと。 
    ''' </summary> 
    Private Sub ArrowMouse(ByVal cnt As Control, ByVal x As Integer, ByVal y As Integer)

        If x >= (cnt.Width - 5) Then
            'コントロールの右端から内側に5ピクセル内にマウスがあるときサイズ変更可能 
            Me.Cursor = Cursors.SizeNWSE
            IsSizable = True
        Else
            'それ以外のときサイズ変更不可。 
            Me.Cursor = Cursors.Default
            IsSizable = False
        End If

    End Sub


投稿者 hori  (社会人) 投稿日時 2009/12/3 21:26:07

PictureBox1.SizeMode = PictureBoxSizeMode.StretchImageをzooomに変更したことで
上記の問題がでたようです。
しかし、ここはzoomのほうが拡大、縮小しても縦横比が保持されるのでよいのですが