2016-03-30 64 views
-1

更新:将代码更改为更新的版本。通过GDI的图像对比度/伽玛/亮度+

我在这里找到了一些关于stackoverflow的代码,但我不是很满意。我对GDI +不是很熟悉,所以也许这是一个愚蠢的问题。

我有一个类来设置亮度/对比度/伽玛:

public class ImageManipulation : IDisposable 
{ 
    Bitmap _internalBitmapMemory; 

    public ImageManipulation(Bitmap bitmap) 
    { 
     _internalBitmapMemory = new Bitmap(bitmap); 
    } 

    public Bitmap AdjustContrast(float Contrast = 1, float Brightness = 1, float Gamma = 1) 
    { 
     float brightness = Brightness;  // no change in brightness 
     float contrast = Contrast;   // twice the contrast 
     float gamma = Gamma;    // no change in gamma 

     float adjustedBrightness = brightness - 1.0f; 

     // create matrix that will brighten and contrast the image 
     float[][] ptsArray = 
     { 
      new float[] {contrast,    0,      0,      0,     0},  // scale red 
      new float[] {0,      contrast,    0,      0,     0},  // scale green 
      new float[] {0,      0,      contrast,    0,     0},  // scale blue 
      new float[] {0,      0,      0,      1.0f,    0},  // don't scale alpha 
      new float[] {adjustedBrightness, adjustedBrightness,  adjustedBrightness,  0,     1} 
     }; 

     var imageAttributes = new ImageAttributes(); 

     imageAttributes.ClearColorMatrix(); 
     imageAttributes.SetColorMatrix(new ColorMatrix(ptsArray), ColorMatrixFlag.Default, ColorAdjustType.Bitmap); 
     imageAttributes.SetGamma(gamma, ColorAdjustType.Bitmap); 

     Graphics g = Graphics.FromImage(_internalBitmapMemory); 

     g.DrawImage(_internalBitmapMemory, new Rectangle(0, 0, _internalBitmapMemory.Width, _internalBitmapMemory.Height) 
      , 0, 0, _internalBitmapMemory.Width, _internalBitmapMemory.Height, 
      GraphicsUnit.Pixel, imageAttributes); 

     g.Dispose(); 

     return _internalBitmapMemory; 
    } 

    public void Dispose() 
    { 
     _internalBitmapMemory.Dispose(); 
     _internalBitmapMemory = null; 
    } 
} 

现在,我得到了一些问题:

1)性能变得n次迭代后低。 2)如果GC太慢而无法清除内存,则会对内存进行处理。我现在试图通过使用一个类并使用using语句创建引用来解决此问题。

这工作到目前为止,但现在我的图像被放置之前它显示。 GRML!

我该如何优化/使其运行整个事情?

+1

请看[这里](http://stackoverflow.com/questions/12709360/whats-the-difference-between-bitmap-clone-and-new-bitmapbitmap)为什么Clone对你没用。最终,您还需要确保处理您创建的尽可能多的位图。 'g.DrawImageUnscaled(backimage')绘制一张空的图像,因为backimage是空的 – TaW

+1

从来没有使用Dispose()方法是一个传统的.NET编程错误。是的,Bitmap类是单数类,提醒你这不是真正可选的,它使用了很多非托管内存 –

+0

@Hans:我在哪里可以处理任何东西? – AllDayPiano

回答

-1

我明白了。没什么大不了的,但一些乱七八糟的与图形对象:

Bitmap _bitmap; 

private void BuildImage() 
{ 
    using (ImageManipulation cls = new ImageManipulation(_bitmap)) 
    { 
     ImageBox.Image.Dispose(); 
     ImageBox.Image = (Bitmap)cls.AdjustContrast((float)nudContrast.Value, (float)nudBrightness.Value, (float)nudGamma.Value).Clone(); 
    } 
} 

public class ImageManipulation : IDisposable 
{ 
    Bitmap _internalBitmapMemory; 

    public ImageManipulation(Bitmap bitmap) 
    { 
     _internalBitmapMemory = new Bitmap(bitmap); 
    } 

    public Bitmap AdjustContrast(float Contrast = 1, float Brightness = 1, float Gamma = 1) 
    { 
     float brightness = Brightness;  // no change in brightness 
     float contrast = Contrast;   // twice the contrast 
     float gamma = Gamma;    // no change in gamma 

     float adjustedBrightness = brightness - 1.0f; 

     // create matrix that will brighten and contrast the image 
     float[][] ptsArray = 
     { 
      new float[] {contrast,    0,      0,      0,     0},  // scale red 
      new float[] {0,      contrast,    0,      0,     0},  // scale green 
      new float[] {0,      0,      contrast,    0,     0},  // scale blue 
      new float[] {0,      0,      0,      1.0f,    0},  // don't scale alpha 
      new float[] {adjustedBrightness, adjustedBrightness,  adjustedBrightness,  0,     1} 
     }; 

     var imageAttributes = new ImageAttributes(); 

     imageAttributes.ClearColorMatrix(); 
     imageAttributes.SetColorMatrix(new ColorMatrix(ptsArray), ColorMatrixFlag.Default, ColorAdjustType.Bitmap); 
     imageAttributes.SetGamma(gamma, ColorAdjustType.Bitmap); 

     Graphics g = Graphics.FromImage(_internalBitmapMemory); 

     g.DrawImage(_internalBitmapMemory, new Rectangle(0, 0, _internalBitmapMemory.Width, _internalBitmapMemory.Height) 
      , 0, 0, _internalBitmapMemory.Width, _internalBitmapMemory.Height, 
      GraphicsUnit.Pixel, imageAttributes); 

     g.Dispose(); 

     return _internalBitmapMemory; 
    } 

    public void Dispose() 
    { 
     _internalBitmapMemory.Dispose(); 
     _internalBitmapMemory = null; 
    } 
} 

问题有关MEM-泄漏是图片框,自动将图像,如果你添加一个新的形象,但仍保留在内存中,直到模具GC,这不是处置将清理混乱。

现在它按预期工作。

可能应该做的是添加深层副本,如果图像不仅仅用于在图片框中显示它。

+0

什么是人们给我的答案评分不好?如果你想让其他人改善他们的自己 - 不要你认为这将有助于给出答案,而不是简单地对它们进行评级?只要没有提供更好的解决方案的建议,没有帮助的简单投票就毫无意义! – AllDayPiano

相关问题