C# - 制作实时更新的BackgroundImage而在其他程序中编辑它(C# - Making

2019-10-17 05:01发布

首先,我已与拖放功能的桌面AIR应用查看瓷砖的图像,但由于一些问题,我已经tryed使在C#中的相同。 你认为什么是更好的选择? (我知道这个小PROGRAMM性能不是问题,但我的意思是两者的dufficulty和复杂性)

我是建设一个简单的TileViewer,所以画面在打开文件对话框中选择和设定为形式平铺的BackgroundImage。

我的问题是:

  1. 我已经使用的计时器(间隔= 500)来重新加载图像,所以,如果我在Photoshop中编辑图像时,T​​ileViewer机器会自动重新加载更新的图像(如我将其保存在Photoshop)。

    但问题是,Photoshop的犯规有premissions这样做辩论,因为图像是在其他PROGRAMM打开(我TileViewer)

  2. 我删除了计时器,并提出了刷新按钮来代替。 但同样的问题。

我认为做的位图数据的副本,但后来我得到我没有为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 );
    }

所以,球员,如果你有任何建议或解决方案,让我知道。

Answer 1:

更新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 );  
}  


Answer 2:

该Bitmap.Clone()方法不会做你希望它做什么。 它创建了一个“浅”副本。 你得到一个新位图对象,但它仍然使用底层像素缓冲区。 包括GDI +使用保持的像素数据从交换文件的内存映射文件。 这又提出一个锁定的文件。

你需要做一个“深”的副本,与位图(图片)构造函数来完成。 像这样:

private void setImage() {
    using (var tempImg = new Bitmap(FileName)) {
        this.BackgroundImage = new Bitmap(tempImg);
    }
}

using语句确保了原始图像设置和锁得到释放。



Answer 3:

你需要用只读标志手动打开文件,然后用手文件的净装入位图。

一个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