画像を動的に読み取って、マウスでドラッグして、その画像を動かすアプリケーションを作りたいと思っています。

[Google Mapsみたいな感じ]
最終的には、Windows Mobileで実装したいと思っているのですが、現在の段階ではPC上で[スマートデバイスではなく]
テストプログラムを作っています。

C#で実装しておりまして、Graphicsに描画した後、
picturebox1.Imageに、Graphicsを入れているのですが、
どうしても画像を移動する際ににカクついてしまいます。ダブルバッファリングなどの対応はしているつもりなのですが・・・。
何かよい方法はないでしょうか。言語はC++,C#,VB,Javaぐらいでしたら、問いませんのでよろしくお願い致します。
Bitmap a2 = new Bitmap(@"./img/22.png");
gg = Graphics.FromImage(bitmapBuffer);
gg.DrawImage(a2, 256, 512);
pictureBox1.Image = bitmapBuffer;
gg.Dispose();

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:
  • 終了:2010/01/15 02:11:34
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:heke2mee No.2

回答回数162ベストアンサー獲得回数43

ポイント100pt

http://q.hatena.ne.jp

こんな感じでどうでしょう

フォームにピクチャーボックス貼って

イベントはつないでくださいね


using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Drawing;

namespace test2

{

public partial class Form2 : Form

{

Bitmap _memImage;

Graphics _gImage;

Point _drawPointOffset;

List<ViewImage> _viewImageList;

//マウスの押された位置

private Point mouseDownPoint = Point.Empty;

private Point mouseDownPointOffset = Point.Empty;

public Form2()

{

InitializeComponent();

_memImage = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);

_gImage = Graphics.FromImage(_memImage);

_gImage.Clear(pictureBox1.BackColor);

}

private void Form2_Load(object sender, EventArgs e)

{

_drawPointOffset = new Point();

_viewImageList = new List<ViewImage>();

ViewImage vimag;

vimag = new ViewImage(new Point(0, 0));

vimag.SourcePicture = new Bitmap(@"./xxx1.png");

_viewImageList.Add(vimag);

vimag = new ViewImage(new Point(100, 0));

vimag.SourcePicture = new Bitmap(@"./xxx2ー.png");

_viewImageList.Add(vimag);

DrawMemImage(_drawPointOffset);

}

private void DrawMemImage(Point point)

{

_gImage.Clear(pictureBox1.BackColor);

foreach (var item in _viewImageList)

{

Point drawPoint = new Point(item.DrawPoint.X + point.X, item.DrawPoint.Y + point.Y);

//ここでクライアント領域内にイメージがあるか判断して

//描画するか判定する(クリッピング処理)

//面倒なので、全部描画

_gImage.DrawImage(item.SourcePicture, drawPoint);

}

}

private void pictureBox1_Paint(object sender, PaintEventArgs e)

{

Graphics g = e.Graphics;

//DrawImageで描画

g.DrawImage(_memImage, new Point());

}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)

{

mouseDownPoint = Point.Empty;

mouseDownPointOffset = Point.Empty;

}

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)

{

if (e.Button == MouseButtons.Left)

{

Point clickPoint = new Point(e.X, e.Y);

mouseDownPoint = new Point(e.X, e.Y);

mouseDownPointOffset = new Point(_drawPointOffset.X - e.X, _drawPointOffset.Y - e.Y);

}

}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)

{

if (mouseDownPoint != Point.Empty)

{

System.Diagnostics.Debug.WriteLine(e.X, ToString() + "," + e.Y.ToString());

_drawPointOffset = new Point(mouseDownPointOffset.X + e.X, mouseDownPointOffset.Y + e.Y);

DrawMemImage(_drawPointOffset);

this.Refresh();

}

}

private void Form2_FormClosing(object sender, FormClosingEventArgs e)

{

_memImage.Dispose();

_gImage.Dispose();

}

}


/// <summary>

/// 画像データのクラス

/// </summary>

class ViewImage

{

private Point _point;

private Bitmap _bitmap;

/// <summary>

/// コンストラクタ

/// </summary>

public ViewImage(Point point)

{

_point = point;

}


public Point DrawPoint

{

set { _point = value; }

get { return _point; }

}

public Bitmap SourcePicture

{

set { _bitmap = value; }

get { return _bitmap; }

}

~ViewImage()

{

System.Diagnostics.Debug.Print("image デストラクタ");

}

}

}

id:ymlab

回答ありがとうございました。id:heke2mee さんの示して下さったコードをそのまま打ち込んでみたら、簡単に実現できました。大変感謝しております。

まだ、Form_Loadでファイルを読み込んで、DrawImageで描画するところが、私には難しいですが、

このプログラムを元に、動的に新たに画像を読み込み、動的に画像を解放するように頑張ってみたいと思います。

[WindowsMobileのメモリの容量が少ないと思うため。]

P.S. System.Diagnostics.Debug.Print ←こんな便利なのがあったのですね^^;

2010/01/15 02:10:55

その他の回答1件)

id:mass3 No.1

回答回数118ベストアンサー獲得回数15

ポイント35pt

PCの性能の問題だったりしませんか?

Javaで実装してみました。

私のPCではカクつかずにスクロールできますが、これもカクつきませんか?

あとはC#で書いたソースコード全体を見せてもらうとわかるかも?

id:ymlab

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

私の環境は、 Windows Vista Buisiness SP1 32bit

CPUは、Quad Core Q9450 2.66GHz

メモリは 8.00GB[そのうち、4.6GBは、LAN]

GeForse 8800 GTS 512MB

でした。

紹介していただいたJavaで実装してみましたのサイトは、問題なくスクロールできます。

また、Google Mapも問題なくできます。

ブラウザでスムーズにできるのだから、アプリケーションでは余裕でできるだろうと思っていたのですが・・・。

ソースコード全体では、以下の様な感じです。

あまりにも必要でないところは消しています[どうでもよい試行錯誤のコメントとか]

本当に、低レベルな内容だと思うのですが、手も足もでません。

申し訳ございませんが、よろしくお願い致します。

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.IO;

using System.Drawing.Imaging;

namespace ImageMovetemp

{

public partial class Form1 : Form

{

public int iMouseStatus = 2;

Point md, mu,delta;//マウスダウンした時のX座標 マウスアップした時のY座標

Bitmap bitmapBuffer;

Image aa;

Graphics gg;

Bitmap abc, a1, a2,b0,b1,b2;

public Form1()

{

InitializeComponent();

// bitmapBuffer = new Bitmap(pictureBox1.Image);

//abc = new Bitmap(256, 256);

abc = new Bitmap(@"./img/21.png");

a2 = new Bitmap(@"./img/22.png");

a1 = new Bitmap(@"./img/20.png");

b0 = new Bitmap(@"./img/10.png");

b1 = new Bitmap(@"./img/11.png");

b2 = new Bitmap(@"./img/12.png");

}

private void button1_Click(object sender, EventArgs e)

{

//ピクチャボックスを移動する

pictureBox1.Location = new Point(-100, -100);

}

private void button2_Click(object sender, EventArgs e)

{

//画像の読み込み

gg = Graphics.FromImage(bitmapBuffer);

gg.DrawImage(abc, 120, 256);

gg.DrawImage(a1, 256, 0);

gg.DrawImage(a2, 256, 512);

gg.DrawImage(b0, -100, 0);

gg.DrawImage(b1, -100, 256);

gg.DrawImage(b2, -100, 512);

pictureBox1.Image = bitmapBuffer;

gg.Dispose();

abc.Dispose();

}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)

{

iMouseStatus = 2;

label1.Text = "マウスが放された";

label2.Text = "X="+ e.X + " Y="+e.Y;

mu.X = e.X; mu.Y = e.Y;

}

private void pictureBox1_DoubleClick(object sender, EventArgs e)

{

MessageBox.Show("ダブルクリック");

}

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)

{

if ( iMouseStatus == 3 ) {return;}

iMouseStatus = 1; //マウスが押下された

label1.Text = "マウスが押下された";

md.X = e.X; md.Y = e.Y;

label5.Text = "X=" + e.X + " Y=" + e.Y;

}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)

{

if (iMouseStatus != 1) { return; }

label1.Text = "ドラッグ移動中";

delta.X = e.X - md.X; delta.Y = e.Y - md.Y;

label7.Text = "dX=" + delta.X + " dy= " + delta.Y;

gg = Graphics.FromImage(pictureBox1.Image);

abc = (Bitmap)bitmapBuffer.Clone();

md.X = e.X; md.Y = e.Y;

gg.DrawImage(abc, this.delta.X, this.delta.Y);

pictureBox1.Image = bitmapBuffer;

}


private void Form1_Load(object sender, EventArgs e)

{

/** ダブルバッファリングをさせる*/

this.DoubleBuffered = true;

this.bitmapBuffer = new Bitmap(pictureBox1.Width, pictureBox1.Height);

abc = new Bitmap(bitmapBuffer.Width, bitmapBuffer.Height, PixelFormat.Format32bppRgb);

}

}

}

2010/01/11 21:50:34
id:heke2mee No.2

回答回数162ベストアンサー獲得回数43ここでベストアンサー

ポイント100pt

http://q.hatena.ne.jp

こんな感じでどうでしょう

フォームにピクチャーボックス貼って

イベントはつないでくださいね


using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Drawing;

namespace test2

{

public partial class Form2 : Form

{

Bitmap _memImage;

Graphics _gImage;

Point _drawPointOffset;

List<ViewImage> _viewImageList;

//マウスの押された位置

private Point mouseDownPoint = Point.Empty;

private Point mouseDownPointOffset = Point.Empty;

public Form2()

{

InitializeComponent();

_memImage = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);

_gImage = Graphics.FromImage(_memImage);

_gImage.Clear(pictureBox1.BackColor);

}

private void Form2_Load(object sender, EventArgs e)

{

_drawPointOffset = new Point();

_viewImageList = new List<ViewImage>();

ViewImage vimag;

vimag = new ViewImage(new Point(0, 0));

vimag.SourcePicture = new Bitmap(@"./xxx1.png");

_viewImageList.Add(vimag);

vimag = new ViewImage(new Point(100, 0));

vimag.SourcePicture = new Bitmap(@"./xxx2ー.png");

_viewImageList.Add(vimag);

DrawMemImage(_drawPointOffset);

}

private void DrawMemImage(Point point)

{

_gImage.Clear(pictureBox1.BackColor);

foreach (var item in _viewImageList)

{

Point drawPoint = new Point(item.DrawPoint.X + point.X, item.DrawPoint.Y + point.Y);

//ここでクライアント領域内にイメージがあるか判断して

//描画するか判定する(クリッピング処理)

//面倒なので、全部描画

_gImage.DrawImage(item.SourcePicture, drawPoint);

}

}

private void pictureBox1_Paint(object sender, PaintEventArgs e)

{

Graphics g = e.Graphics;

//DrawImageで描画

g.DrawImage(_memImage, new Point());

}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)

{

mouseDownPoint = Point.Empty;

mouseDownPointOffset = Point.Empty;

}

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)

{

if (e.Button == MouseButtons.Left)

{

Point clickPoint = new Point(e.X, e.Y);

mouseDownPoint = new Point(e.X, e.Y);

mouseDownPointOffset = new Point(_drawPointOffset.X - e.X, _drawPointOffset.Y - e.Y);

}

}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)

{

if (mouseDownPoint != Point.Empty)

{

System.Diagnostics.Debug.WriteLine(e.X, ToString() + "," + e.Y.ToString());

_drawPointOffset = new Point(mouseDownPointOffset.X + e.X, mouseDownPointOffset.Y + e.Y);

DrawMemImage(_drawPointOffset);

this.Refresh();

}

}

private void Form2_FormClosing(object sender, FormClosingEventArgs e)

{

_memImage.Dispose();

_gImage.Dispose();

}

}


/// <summary>

/// 画像データのクラス

/// </summary>

class ViewImage

{

private Point _point;

private Bitmap _bitmap;

/// <summary>

/// コンストラクタ

/// </summary>

public ViewImage(Point point)

{

_point = point;

}


public Point DrawPoint

{

set { _point = value; }

get { return _point; }

}

public Bitmap SourcePicture

{

set { _bitmap = value; }

get { return _bitmap; }

}

~ViewImage()

{

System.Diagnostics.Debug.Print("image デストラクタ");

}

}

}

id:ymlab

回答ありがとうございました。id:heke2mee さんの示して下さったコードをそのまま打ち込んでみたら、簡単に実現できました。大変感謝しております。

まだ、Form_Loadでファイルを読み込んで、DrawImageで描画するところが、私には難しいですが、

このプログラムを元に、動的に新たに画像を読み込み、動的に画像を解放するように頑張ってみたいと思います。

[WindowsMobileのメモリの容量が少ないと思うため。]

P.S. System.Diagnostics.Debug.Print ←こんな便利なのがあったのですね^^;

2010/01/15 02:10:55

コメントはまだありません

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません