首先,我已与拖放功能的桌面AIR应用查看瓷砖的图像,但由于一些问题,我已经tryed使在C#中的相同。 你认为什么是更好的选择? (我知道这个小PROGRAMM性能不是问题,但我的意思是两者的dufficulty和复杂性)
我是建设一个简单的TileViewer,所以画面在打开文件对话框中选择和设定为形式平铺的BackgroundImage。
我的问题是:
我已经使用的计时器(间隔= 500)来重新加载图像,所以,如果我在Photoshop中编辑图像时,TileViewer机器会自动重新加载更新的图像(如我将其保存在Photoshop)。
但问题是,Photoshop的犯规有premissions这样做辩论,因为图像是在其他PROGRAMM打开(我TileViewer)
我删除了计时器,并提出了刷新按钮来代替。 但同样的问题。
我认为做的位图数据的副本,但后来我得到我没有为32PX X 32PX IMG足够多的内存错误。
我的代码:
private string FileName;
public Form1() {
InitializeComponent();
FileName = "";
}
// OPEN FILE btn
private void button1_Click( object sender, EventArgs e ) {
openFileDialog1.Filter = "PNG Files (*.png)|*.png|JPG Files (*.jpg)|*.jpg";
if(openFileDialog1.ShowDialog() == DialogResult.OK) {
button2.Enabled = true;
FileName = openFileDialog1.FileName;
setImage();
}
}
// REFRESH btn
private void button2_Click( object sender, EventArgs e ) {
if( FileName != "" ) {
setImage();
}
}
private void setImage() {
Bitmap tempImg = new Bitmap( FileName );
Rectangle rect = new Rectangle(0, 0, 100, 100);
PixelFormat format = tempImg.PixelFormat;
this.BackgroundImage = new Bitmap( FileName ).Clone( rect, format );
}
所以,球员,如果你有任何建议或解决方案,让我知道。
更新2:
另一个问题是为线矩形RECT =新的Rectangle(0,0,100,100);
其中,在构造函数中,你应该通过新的形象不是arbitary值100一样的宽度和heigth。
这就是为什么在运行时说,你出的内存! (这为我做的,我有一个18 GB的怪兽机)
更新:
your're泄漏对象因此内存溢出异常
(Haans已经警告过你关于处置对象多数民众赞成。)
试试下面的代码
private string FileName;
public Form1()
{
InitializeComponent();
FileName = "";
}
// OPEN FILE btn
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "PNG Files (*.png)|*.png|JPG Files (*.jpg)|*.jpg";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
FileName = openFileDialog1.FileName;
setImage();
}
}
// REFRESH btn
private void button2_Click(object sender, EventArgs e)
{
if (FileName != "")
{
setImage();
}
}
private void setImage()
{
Stream str=new FileStream(FileName,FileMode.Open, FileAccess.Read,FileShare.Read);
Bitmap tempImg= new Bitmap(Bitmap.FromStream(str));
str.Close();
using( tempImg)
{
Rectangle rect = new Rectangle(0, 0, tempImg.Width, tempImg.Height);
PixelFormat format = tempImg.PixelFormat;
this.BackgroundImage = new Bitmap(tempImg);
}
}
OLD回答
像杰森说
你可能需要做somethinglike这在setimage方法
Stream str = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);
this.BackgroundImage = Bitmap.FromStream(str);
str.Close();
请注意,你最好关闭你打开你使用后的任何流。
代替
私人无效setImage(){
位图tempImg =新的位图(文件名); <---矩形RECT =新的Rectangle(0,0,100,100);
的PixelFormat格式= tempImg.PixelFormat;
this.BackgroundImage = new Bitmap( FileName ).Clone( rect, format );
}
该Bitmap.Clone()方法不会做你希望它做什么。 它创建了一个“浅”副本。 你得到一个新位图对象,但它仍然使用底层像素缓冲区。 包括GDI +使用保持的像素数据从交换文件的内存映射文件。 这又提出一个锁定的文件。
你需要做一个“深”的副本,与位图(图片)构造函数来完成。 像这样:
private void setImage() {
using (var tempImg = new Bitmap(FileName)) {
this.BackgroundImage = new Bitmap(tempImg);
}
}
using语句确保了原始图像设置和锁得到释放。
你需要用只读标志手动打开文件,然后用手文件的净装入位图。
一个alternitive将要复制的文件,然后打开该副本。
看看你是否CNA运行下面的代码,而Photoshop中打开了该文件
FileStream s2 = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read);
文章来源: C# - Making a BackgroundImage update in real time while editing it in other programs