[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();
こんな感じでどうでしょう
フォームにピクチャーボックス貼って
イベントはつないでくださいね
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 デストラクタ");
}
}
}
PCの性能の問題だったりしませんか?
私のPCではカクつかずにスクロールできますが、これもカクつきませんか?
あとはC#で書いたソースコード全体を見せてもらうとわかるかも?
回答ありがとうございました。
私の環境は、 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);
}
}
}
こんな感じでどうでしょう
フォームにピクチャーボックス貼って
イベントはつないでくださいね
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:heke2mee さんの示して下さったコードをそのまま打ち込んでみたら、簡単に実現できました。大変感謝しております。
まだ、Form_Loadでファイルを読み込んで、DrawImageで描画するところが、私には難しいですが、
このプログラムを元に、動的に新たに画像を読み込み、動的に画像を解放するように頑張ってみたいと思います。
[WindowsMobileのメモリの容量が少ないと思うため。]
P.S. System.Diagnostics.Debug.Print ←こんな便利なのがあったのですね^^;
回答ありがとうございました。id:heke2mee さんの示して下さったコードをそのまま打ち込んでみたら、簡単に実現できました。大変感謝しております。
まだ、Form_Loadでファイルを読み込んで、DrawImageで描画するところが、私には難しいですが、
このプログラムを元に、動的に新たに画像を読み込み、動的に画像を解放するように頑張ってみたいと思います。
[WindowsMobileのメモリの容量が少ないと思うため。]
P.S. System.Diagnostics.Debug.Print ←こんな便利なのがあったのですね^^;