C# GDI+ 簡単な描画 (4)

Dec 17, 2016 am 09:49 AM

以前の記事で GDI+ を使用して描画する方法を紹介し、スクリーンショットの例を作成しました。この記事では、Windows の描画に似たツールを作成する方法を紹介します。強力なツールを作成する 描画ツールを作成するには、GDI を習得するだけでは不十分です。現時点では、比較的単純な描画ツールしか作成できません。欠陥がある場合はご相談ください。

まずは最終的な効果を見てみましょう:

c# GDI+简单绘图

主な機能: 直線、長方形、消しゴム、円を描く、色の切り替え、画像を開く、画像を保存する、画像をクリアする、キャンバス サイズを手動で調整する。ソフトウェアが最初に起動すると、空白のキャンバスが表示されます。キャンバスに直接描画することも、メニューの「開く」から画像をインポートして、その画像に描画することもできます。

プラットフォーム:VS2005 WINFORM

コードが多すぎるため、ここでは制作手順を簡単に紹介し、プロジェクトのダウンロードを提供します。

1.インターフェース全体をレイアウトします。
2. 描画ツールの機能を実装します
3. カラーピッキングの機能を実装します ここでは前回書いたカスタムコントロールを直接使用します。
4. メニュー機能を実装します
5. キャンバスサイズを手動で調整する機能を実装します
6. テスト

描画ツールの機能を実装します
コードをより一貫性のあるものにするために、いくつかのデザインパターンを使用しました。あまり上手ではないので、コードはまだちょっと汚いですが、ふふ!描画ツールに関するこれらすべての機能ブロックは、DrawTools クラスに記述されます。次に、メイン フォームでは、特定の描画コードをあまり必要とせずに、このクラスを呼び出すだけで描画が完了します。このクラスの描画ツールで提供される主なツールは、鉛筆、消しゴム、直線、長方形、円、塗りつぶし長方形、塗りつぶし円です。これらの関数ブロックのコードは、これまでの記事をよく読んでいれば理解できるはずです。
ここで注意すべき点は次のとおりです:
1. 描画プロセスの不要な痕跡が記録されないようにするにはどうすればよいですか?
この問題については 3 番目の記事で言及されていますので、まずその記事を読んでください。コードを読みやすくするために、2 つの Image 変数を設定しました。finishImg は描画プロセスのトレースを保存するために使用され、originalImg は完了した描画プロセスと初期の背景画像を保存するために使用されます。
2. このクラスはメインフォームとどのように通信しますか?
もちろん、これらのファンクションブロックをメインフォームに直接記述すれば、そのような問題は発生しません。ただし、ツール コードのみに問題がある場合は、コードが非常にわかりにくくなり、プロジェクト全体を変更する必要があります。ここでは、メイン フォームがプロパティに値を割り当てることでアートボード、キャンバス、カラーに関する情報をツール クラスに渡し、対応するツール メソッドを呼び出すことでこれらのツールを使用できるようにメソッドとプロパティを定義します。
3. 主要な属性
これらのツールが適切に動作するためには、ターゲットのアートボード (つまり、ピクチャーボックス)、描画カラー、および元のキャンバスを彼に渡す必要があります。

メニュー機能を実装するには

c# GDI+简单绘图

ここでファイル操作を少し理解する必要がありますが、関連する情報を確認できます。

主な困難は、「開く」メニュー項目の実装です
変更後に開いた画像を再保存したい場合は、開いた後にファイルを閉じる必要があります。そうしないと、ファイルが開いているため、元のファイルが上書きされません。これにより、コンパイル中に「GDI General Error」がポップアップ表示されます。したがって、インターネット上の他の友人のやり方によれば、まず開いている画像を GDI+ 経由で別のキャンバスに描画し、その後、開いている画像と画像の描画に使用した描画ボードをすぐに閉じます。

 private void openPic_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();//实例化文件打开对话框
            ofd.Filter = "JPG|*.jpg|Bmp|*.bmp|所有文件|*.*";//设置对话框打开文件的括展名
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                Bitmap bmpformfile = new Bitmap(ofd.FileName);//获取打开的文件
                panel2.AutoScrollPosition = new Point(0,0);//将滚动条复位
                pbImg.Size = bmpformfile.Size;//调整绘图区大小为图片大小

                reSize.Location = new Point(bmpformfile.Width, bmpformfile.Height);//reSize为我用来实现手动调节画布大小用的
                //因为我们初始时的空白画布大小有限,"打开"操作可能引起画板大小改变,所以要将画板重新传入工具类
                dt.DrawTools_Graphics = pbImg.CreateGraphics();

                Bitmap bmp = new Bitmap(pbImg.Width, pbImg.Height);
                Graphics g = Graphics.FromImage(bmp);
                g.FillRectangle(new SolidBrush(pbImg.BackColor), new Rectangle(0, 0, pbImg.Width, pbImg.Height));//不使用这句话,那么这个bmp的背景就是透明的
                g.DrawImage(bmpformfile, 0, 0,bmpformfile.Width,bmpformfile.Height);//将图片画到画板上
                g.Dispose();//释放画板所占资源
                //不直接使用pbImg.Image = Image.FormFile(ofd.FileName)是因为这样会让图片一直处于打开状态,也就无法保存修改后的图片
                bmpformfile.Dispose();//释放图片所占资源
                g = pbImg.CreateGraphics();
                g.DrawImage(bmp, 0, 0);
                g.Dispose();
                dt.OrginalImg = bmp;
                bmp.Dispose();
                sFileName = ofd.FileName;//储存打开的图片文件的详细路径,用来稍后能覆盖这个文件
                ofd.Dispose();

            }
        }
ログイン後にコピー

画像のクリアとは、実際にはキャンバス全体を白で塗りつぶすことです

その他は比較的簡単なので、ここでは詳しく説明しません。

キャンバスサイズの手動調整を実現
ネット上ではAPIを使えという人もいますが、個人的には他のコントロールを使ったほうが簡単だと思います、少なくとも理解はできます。
アイデア:picturebox1(サイズ5*5)を配置し、メイン描画ボードの右下隅に固定し、マウスが入ったときのカーソルを矢印の形に変更し、マウスを押して移動したときのイベントを設定し、そして、picturebox1 をマウスの動きに追従させます。マウスを離したら、メイン描画ボードの右下隅の座標をpicturebox1の座標に合わせます。
コードを見てみましょう:
reSize は、ヘルプに使用するピクチャーボックス コントロールです

private bool bReSize = false;//是否改变画布大小
        private void reSize_MouseDown(object sender, MouseEventArgs e)
        {
            bReSize = true;//当鼠标按下时,说明要开始调节大小
        }

        private void reSize_MouseMove(object sender, MouseEventArgs e)
        {
            if (bReSize)
            {
                reSize.Location = new Point(reSize.Location.X + e.X, reSize.Location.Y + e.Y);

            }
        }

        private void reSize_MouseUp(object sender, MouseEventArgs e)
        {
            bReSize = false;//大小改变结束
            //调节大小可能造成画板大小超过屏幕区域,所以事先要设置autoScroll为true.
            //但是滚动条的出现反而增加了我们的难度,因为滚动条上下移动并不会自动帮我们调整图片的坐标。
            //这是因为GDI绘图的坐标系不只一个,好像有三个,没有仔细了解,一个是屏幕坐标,一个是客户区坐标,还个是文档坐标。
            //滚动条的上下移动改变的是文档的坐标,但是客户区坐标不变,而location属性就属于客户区坐标,所以我们直接计算会出现错误
            //这时我们就需要知道文档坐标与客户区坐标的偏移量,这就是AutoScrollPostion可以提供的

            pbImg.Size = new Size(reSize.Location.X - (this.panel2.AutoScrollPosition.X), reSize.Location.Y - (this.panel2.AutoScrollPosition.Y));
            dt.DrawTools_Graphics = pbImg.CreateGraphics();//因为画板的大小被改变所以必须重新赋值

            //另外画布也被改变所以也要重新赋值
            Bitmap bmp = new Bitmap(pbImg.Width, pbImg.Height);
            Graphics g = Graphics.FromImage(bmp);
            g.FillRectangle(new SolidBrush(Color.White), 0, 0, pbImg.Width, pbImg.Height);
            g.DrawImage(dt.OrginalImg, 0, 0);
            g.Dispose();
            g = pbImg.CreateGraphics();
            g.DrawImage(bmp, 0, 0);
            g.Dispose();
            dt.OrginalImg = bmp;

            bmp.Dispose();
        }
ログイン後にコピー

効果は以下に示すとおりです (白い領域の右下隅をよく見てください):

c# GDI+简单绘图

この時点で、小さな四角をドラッグして画像サイズを調整できます。

このようにして、主な問題はほぼ解決されましたが、まだ不十分な点もいくつかありますので、皆様、貴重なご意見をお待ちしております。


その他の c# GDI+ 簡単な描画 (4) 関連記事については、PHP 中国語 Web サイトに注目してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

C言語のnullの代替案は何ですか C言語のnullの代替案は何ですか Mar 03, 2025 pm 05:37 PM

この記事では、CのNull Poernter recerferenceの課題を調査します。問題は、問題はnullではなく、その誤用であると主張しています。 記事では、参照前のチェック、ポインターInitialiなど、非参照を防止するためのベストプラクティスの詳細

どの言語コンパイラが優れていますか? どの言語コンパイラが優れていますか? Mar 03, 2025 pm 05:39 PM

この記事は、Cコンパイラの選択に関する初心者を案内しています。 GCCは、使いやすさ、幅広い可用性、広範なリソースが初心者に最適であるため、最適であると主張しています。 ただし、GCC、Clang、MSVC、およびTCCも比較して、その違いを強調しています

次のレベルのCコンパイラを追加する方法 次のレベルのCコンパイラを追加する方法 Mar 03, 2025 pm 05:44 PM

この記事では、printf内の\ nエスケープシーケンスを使用してcで新しいライン文字を作成し、関数を置く方法について説明します。 機能を詳しく説明し、出力のラインブレークに使用することを示すコード例を提供します。

nullは、C言語での最新のプログラミングではまだ重要ですか? nullは、C言語での最新のプログラミングではまだ重要ですか? Mar 03, 2025 pm 05:35 PM

この記事では、現代のCプログラミングにおけるNullの継続的な重要性を強調しています。 進歩にもかかわらず、Nullは明示的なポインター管理にとって重要なままであり、有効なメモリアドレスがないことをマークすることにより、セグメンテーションの障害を防ぎます。 最高のPRAC

C言語コンパイラのWebバージョンは何ですか? C言語コンパイラのWebバージョンは何ですか? Mar 03, 2025 pm 05:42 PM

この記事では、初心者向けのオンラインCコンパイラをレビューし、使いやすさとデバッグ機能に焦点を当てています。 OnlineGDBとRepl.itは、ユーザーフレンドリーなインターフェイスと役立つデバッグツールのために強調表示されます。 プログラムやコンパイルなどのその他のオプション

c言語オンラインプログラミングウェブサイトc言語コンパイラ公式ウェブサイトの要約 c言語オンラインプログラミングウェブサイトc言語コンパイラ公式ウェブサイトの要約 Mar 03, 2025 pm 05:41 PM

この記事では、オンラインCプログラミングプラットフォームを比較し、デバッグツール、IDE機能、標準コンプライアンス、メモリ/実行の制限などの機能の違いを強調しています。 「最良の」プラットフォームはユーザーのニーズに依存していると主張しています。

C言語コンパイラによるコードをコピーする方法 C言語コンパイラによるコードをコピーする方法 Mar 03, 2025 pm 05:43 PM

この記事では、C IDEでの効率的なコードコピーについて説明します。 コピーはコンパイラ機能ではなくIDE機能であり、IDE選択ツールの使用、コード折りたたみ、検索/交換、テンプラなど、効率を向上させるための詳細戦略であることを強調しています。

C言語コンパイラによって出力ウィンドウをポップアップしないという問題を解決する方法 C言語コンパイラによって出力ウィンドウをポップアップしないという問題を解決する方法 Mar 03, 2025 pm 05:40 PM

この記事では、Cプログラムのコンパイルでの出力Windowsの欠落をトラブルシューティングします。 実行可能ファイルの実行に失敗し、プログラムエラー、誤ったコンパイラ設定、バックグラウンドプロセス、迅速なプログラム終了などの原因を調べます。ソリューションにはchが含まれます

See all articles