none
BackgroundImageだけを設定したPictureBoxを拡大して表示したい RRS feed

  • 質問

  • 教えていただきたいのですが、BackgroundImageだけを設定したPictureBoxを拡大して表示するには

    どうすれば良いでしょうか。c1はPictureBoxでサイズは縦横16ピクセルです。

    ZoomやStretchImageを使うではなく、拡大表示をしたいです。

    c1.BackgroundImage= global::ZoomUpDown.Properties.Resources.b2;
    			c1.Location = new Point(0, 0);
    			c1.Image = new Bitmap(c1.Width,c1.Height);
    			Graphics g = Graphics.FromImage(c1.Image);
    			g.FillRectangle(new SolidBrush(Color.Transparent),0f,0f,16f,16f);
    			c1.SizeMode = PictureBoxSizeMode.AutoSize;
    			Bitmap bmp = new Bitmap(c1.Image,
    	  c1.Image.Width * 10,
    	  c1.Image.Height * 10);
    			pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
    			pictureBox1.Image = bmp;
    

    c1.BackgroundImage= global::ZoomUpDown.Properties.Resources.b2;
    			c1.Location = new Point(0, 0);
    			c1.Image = new Bitmap(c1.Width,c1.Height);
    			Graphics g = Graphics.FromImage(c1.Image);
    			g.FillRectangle(new SolidBrush(Color.Transparent),0f,0f,16f,16f);
    g.ResetTransform();
    			g.ScaleTransform(10f, 10f);
    			
    			g.DrawImage(c1.Image, 0f, 0f);
    			
    			
    

    のようなコードを書いてみたのですが、表示状態は16×16ピクセルの画像のままです。

    どなたか教えていただけないでしょうか。

    2010年12月25日 2:04

回答

  • 最初に書かれたコードですが、c1 と pictureBox1 の関係とか、BackgroundImage と Image の関係とか、よくわからない部分がありますね。(^^;
    新しい話に行くまでに、まずは最初のコードが期待通りに表示されるようにもう少しあがいてみてもいいのではと思いました。
    (ちなみに今回の最終目標を考えると、ScaleTransform は使われない方が良さそうに思います。)

    次に新しい話についてですが、ポインターの座標がどの領域に含まれるのかを計算で求めると良いと思いました。
    座標を格子の幅や高さで割ることで、何番目の格子に位置するか計算できますよね。
    ただ、それが RectangleF[] Rects のどれか?ということになりますが、この配列自体、メリットがないと思います。
    2次元配列にする手はもちろんありますが、そもそも格子は縦線と横線の描画でできますし、都度計算で求めて RectangleF を作成すればいいですし。

    最後に、方針がかなり変わりますが、DataGridView をエディタのインターフェイスに利用すると、比較的作成しやすそうに思いました。
    DataGridView 自体、複雑なコントロールなので、もし使われたことがなければ使いこなすだけで大変かもしれませんが、適切にイベントを利用するだけできっとできちゃうと思います。
    クラスを作ったりするプログラミングの勉強でしたら、ズルになっちゃいますけど。(^^;


    助言ありがとうございます。後で書いたクラスの方でなんとか思い通りの動きが出来ました。(動きが重いですけど)

    DataGridViewのインターフェイスについても教えていただきありがとうございました。

    あと、最初に書いた分かりづらいコードの方もあがいてみようと思います。

    • 回答としてマーク 馬鹿1号 2010年12月28日 18:13
    2010年12月27日 22:03

すべての返信

  • ImageLayout.Zoomを設定するのが定石だと思いますが、なぜZoom以外の方法で拡大したいのかを説明していただくと、回答がつくかもしれません。

    ImageLayout 列挙体 (System.Windows.Forms)


    Blog:プログラマーな日々 http://d.hatena.ne.jp/JHashimoto/
    • 編集済み jhashimoto 2010年12月25日 2:59 文言を変更
    2010年12月25日 2:56
  • どういったコードであるかを理解してコードを使っていますか?
    ざっくりと読ませて頂く限り、意味を理解せずにそのまま使って、「うまくいかない」と言われているようにお見受けします。
    サンプルコードを参照される際には、どの部分がどういったことをしているのか考えてみてください。

    適当につぎはぎしてうまく動いてもその場しのぎにしかなりません。
    今後、自分でいろいろと作っていくためにも、どの部分が何をしているものかを考える、調べる、学ぶ、教えてもらうといったことが求められます。(今後応用していくためにも、必要なスキルです)

    表示状態は16×16ピクセルの画像のままです。

    答えは、何もしていないからです。
    透明な画像に何をしようが透明なままで、それを Image プロパティに設定しても画面に変化を与えることはありません。

    さて、このコードはいったい、何を拡大しようとしているのでしょうか?
    そして、やりたいことはどの画像を拡大することだったのでしょうか?

    今一度、お考えください。
    (拡大したいものは global::ZoomUpDown.Properties.Resources.b2 だったはずですよね)


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2010年12月25日 13:39
    モデレータ
  • すいませんでした。正直に言います。アイコンエディタを作ってみたくて以下のようなクラスを作りました。

     

    public enum SIZETYPE:int
    	{
    		SIZE16 = 16,
    		SIZE32 = 32,
    		SIZE48 = 48,
    	}
    	public delegate void PictureBoxImageChange(Canvas c, EventImageArgs pe);
    	public class Canvas:PictureBox
    	{
    		public event PictureBoxImageChange PictureBoxImageChange;
    		public Canvas()
    		{
    			if (Sizetype == SIZETYPE.SIZE16)
    			{
    				this.Width = 10 * (int)sizeType;
    				this.Height = 10 * (int)sizeType;
    				this.Location = new Point(0, 0);
    				this.Size = new Size(160, 160);
    				this.SizeMode = PictureBoxSizeMode.AutoSize;
    				panel1.Size = new Size(160, 160);
    				panel1.AutoScroll = true;
    				panel1.Margin = new System.Windows.Forms.Padding(0);
    				panel1.Controls.Add(this);
    				Init16();
    			}
    			
    		}
    		private Panel panel1 = new Panel();
    		
    		public const int STEP = 10;
    		int size =16;
    
    		
    		public int DrawSize
    		{
    			get { return size; }
    			set { size = value; }
    		}
    		RectangleF[] Rects;
    
    		SIZETYPE sizeType = SIZETYPE.SIZE16;
    		public SIZETYPE Sizetype
    		{
    			set { sizeType = value; }
    			get { return sizeType; }
    		}
    		//PictureBox pictBox = new PictureBox();
    
    
    		float step = STEP;
    		public float Step
    		{
    			set { step = value; }
    			get { return step; }
    		}
    		float WIDTH = 160f;
    		public float FWidth
    		{
    			set { WIDTH = value; }
    			get { return WIDTH; }
    		}
    		float HEIGHT = 160f;
    		public float FHeight
    		{
    			set { HEIGHT = value; }
    			get { return HEIGHT; }
    		}
    		float zoom = 1.0f;
    		public float Zoom
    		{
    			set { zoom = value; }
    			get { return zoom; }
    		}
    		public void Init16()
    		{
    
    			float w = (float)(10 * (int)sizeType);
    			float h = (float)(10 * (int)sizeType);
    			w *= Zoom;
    			h *= Zoom;
    			this.FWidth = w;
    			this.FHeight = h;
    			this.Size = new Size(((int)this.FWidth), ((int)this.FHeight));
    			float step = (float)STEP;
    			step *= Zoom;
    			this.Step = step;
    			Rects = new RectangleF[(int)sizeType * (int)sizeType];
    			Graphics g = Graphics.FromImage((this.Image = new Bitmap(this.Width, this.Height)));
    			int l = 0;
    			
    			for (float i = 0; i < this.FWidth; i += Step)
    			{
    
    				for (float j = 0; j < this.FHeight; j += Step)
    				{
    					Rects[l++] = new RectangleF(j, i, Step, Step);
    					
    				}
    			}
    			
    			Pen pen = new Pen(Color.FromArgb(255, 0, 0, 255), 1);
    			g.DrawRectangles(pen,Rects);
    			
    			this.BorderStyle = BorderStyle.None;
    			Rectangle borderRectangle = this.ClientRectangle;
    			borderRectangle.Inflate(0, 0);
    			ControlPaint.DrawBorder3D(g, borderRectangle,
    				Border3DStyle.Raised);
    
    			this.Refresh();
    			g.Dispose();
    			pen.Dispose();
    
    		}
    		public RectangleF[] CnvsRects
    		{
    			get { return Rects; }
    		}
    		public Point ptstart = new Point(-10, -10);
    		public Point ptStart
    		{
    			get { return ptstart; }
    			set { ptstart = value; }
    		}
    		public Point ptend = new Point(-10, -10);
    		public Point ptEnd
    		{
    			get { return ptend; }
    			set { ptend = value; }
    		}
    		
    		public new Image Image
    		{
    			get 
    			{
    				RaisePictureBoxImageChange();
    				return base.Image ;
    				
    			}
    			set
    			{
    				 base.Image = value;
    				RaisePictureBoxImageChange();
    			}
    		}
    
    		void RaisePictureBoxImageChange()
    		{
    			EventImageArgs args = new EventImageArgs(base.Image, ptStart, ptEnd);
    			if(!(ptStart.Equals(new Point(-10,-10)) || ptEnd.Equals(new Point(-10,-10))))
    				OnRaisePictureBoxImageChange(args);
    			
    		}
    		protected virtual void OnRaisePictureBoxImageChange(EventImageArgs ea)
    		{
    			if (PictureBoxImageChange != null)
    			{
    				PictureBoxImageChange(this, ea);
    			}
    		}
    
    
    		
    
    		private void InitializeComponent()
    		{
    			((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
    			this.SuspendLayout();
    			// 
    			// Canvas
    			// 
    			this.Margin = new System.Windows.Forms.Padding(0);
    			this.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
    			((System.ComponentModel.ISupportInitialize)(this)).EndInit();
    			this.ResumeLayout(false);
    
    		}
    	}
    	public class EventImageArgs : EventArgs
    	{
    		private Image image;
    		public Image Image
    		{
    			get { return image; }
    			set { image = value; }
    		}
    		private Point points;
    		public Point ptStart
    		{
    			get { return points; }
    			set { points = value; }
    		}
    		private Point pointe;
    		public Point ptEnd
    		{
    			get { return pointe; }
    			set { pointe = value; }
    		}
    		public EventImageArgs(Image img,Point sp,Point ep)
    		{
    			image = img;
    			points = sp;
    			pointe = ep;
    		}
    	}

     

     

    で、変化のあったポイントをイベントを通じて得て、そのポイントの含んでるRectangleをGraphic.FillRectangleを使ってその四角形を塗りつぶそうと思ったのですか、どうやって、そのポイント群を得るのかがわかりませんでした。

    ですので、16×16ピクセルの画像を拡大して、処理をしていったほうがいいのかなと、思って最初の質問しました。

    ただ、このクラスをつかって変化のあったポイントを知る方法があるなら、是非そちらの方が知りたいです。

    変な質問の仕方をしてすいませんでした。

    • 編集済み 馬鹿1号 2010年12月27日 2:56 間違ってた
    2010年12月27日 2:28
  • 最初に書かれたコードですが、c1 と pictureBox1 の関係とか、BackgroundImage と Image の関係とか、よくわからない部分がありますね。(^^;
    新しい話に行くまでに、まずは最初のコードが期待通りに表示されるようにもう少しあがいてみてもいいのではと思いました。
    (ちなみに今回の最終目標を考えると、ScaleTransform は使われない方が良さそうに思います。)

    次に新しい話についてですが、ポインターの座標がどの領域に含まれるのかを計算で求めると良いと思いました。
    座標を格子の幅や高さで割ることで、何番目の格子に位置するか計算できますよね。
    ただ、それが RectangleF[] Rects のどれか?ということになりますが、この配列自体、メリットがないと思います。
    2次元配列にする手はもちろんありますが、そもそも格子は縦線と横線の描画でできますし、都度計算で求めて RectangleF を作成すればいいですし。

    最後に、方針がかなり変わりますが、DataGridView をエディタのインターフェイスに利用すると、比較的作成しやすそうに思いました。
    DataGridView 自体、複雑なコントロールなので、もし使われたことがなければ使いこなすだけで大変かもしれませんが、適切にイベントを利用するだけできっとできちゃうと思います。
    クラスを作ったりするプログラミングの勉強でしたら、ズルになっちゃいますけど。(^^;

    2010年12月27日 7:35
  • コードをそのまま書いて、「○○をやりたいので、教えてください」では、丸投げと言えます。
    件のクラスは読んでいませんが、もう少し問題を最小化、切り分けできませんか?

    あるできあがったクラスの、どこを直せばよいという指摘を求めることは、そのプログラムを直してくれと丸投げしていることになります。
    それでは今後も同じようなことになりかねませんので、どこをどのように考え、何を試して、どうだったかといった情報の提示や、何がわかれば後は自分で進められるかといったことの整理もお願いします。

    # 最初の質問を撤回して、こっちでのやり方を教えてくれというのはよくわかりません。
    # 最初から完成形を目指しても問題は解決しませんので、少しずつ切り分けて、小さな問題から解消していくことも求められるスキルです。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2010年12月27日 15:57
    モデレータ
  • 最初に書かれたコードですが、c1 と pictureBox1 の関係とか、BackgroundImage と Image の関係とか、よくわからない部分がありますね。(^^;
    新しい話に行くまでに、まずは最初のコードが期待通りに表示されるようにもう少しあがいてみてもいいのではと思いました。
    (ちなみに今回の最終目標を考えると、ScaleTransform は使われない方が良さそうに思います。)

    次に新しい話についてですが、ポインターの座標がどの領域に含まれるのかを計算で求めると良いと思いました。
    座標を格子の幅や高さで割ることで、何番目の格子に位置するか計算できますよね。
    ただ、それが RectangleF[] Rects のどれか?ということになりますが、この配列自体、メリットがないと思います。
    2次元配列にする手はもちろんありますが、そもそも格子は縦線と横線の描画でできますし、都度計算で求めて RectangleF を作成すればいいですし。

    最後に、方針がかなり変わりますが、DataGridView をエディタのインターフェイスに利用すると、比較的作成しやすそうに思いました。
    DataGridView 自体、複雑なコントロールなので、もし使われたことがなければ使いこなすだけで大変かもしれませんが、適切にイベントを利用するだけできっとできちゃうと思います。
    クラスを作ったりするプログラミングの勉強でしたら、ズルになっちゃいますけど。(^^;


    助言ありがとうございます。後で書いたクラスの方でなんとか思い通りの動きが出来ました。(動きが重いですけど)

    DataGridViewのインターフェイスについても教えていただきありがとうございました。

    あと、最初に書いた分かりづらいコードの方もあがいてみようと思います。

    • 回答としてマーク 馬鹿1号 2010年12月28日 18:13
    2010年12月27日 22:03