Browse Source

Do not dispose of source Fix #404

Former-commit-id: 5bcb4977e45de08f9c1c0c15583dc5140356609f
Former-commit-id: 5f21f6f1488a284413427231b76e0ad71eca9240
Former-commit-id: 8a227c50ce892ce7a1189015f3a2bbbb26c6e20d
pull/1/head
James Jackson-South 10 years ago
parent
commit
2ffee6bf4f
  1. 2
      src/ImageProcessorCore/ImageBase.cs
  2. 26
      src/ImageProcessorCore/ImageExtensions.cs
  3. 36
      tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs

2
src/ImageProcessorCore/ImageBase.cs

@ -41,7 +41,7 @@ namespace ImageProcessorCore
/// method will not dispose again. This help not to prolong the entity's
/// life in the Garbage Collector.
/// </remarks>
protected bool IsDisposed;
internal bool IsDisposed;
/// <summary>
/// Initializes a new instance of the <see cref="ImageBase"/> class.

26
src/ImageProcessorCore/ImageExtensions.cs

@ -78,9 +78,7 @@ namespace ImageProcessorCore
/// <returns>The <see cref="Image"/>.</returns>
public static Image Process(this Image source, Rectangle sourceRectangle, IImageProcessor processor)
{
source = PerformAction(source, true, (sourceImage, targetImage) => processor.Apply(targetImage, sourceImage, sourceRectangle));
return source;
return PerformAction(source, true, (sourceImage, targetImage) => processor.Apply(targetImage, sourceImage, sourceRectangle));
}
/// <summary>
@ -94,7 +92,7 @@ namespace ImageProcessorCore
/// <param name="height">The target image height.</param>
/// <param name="sampler">The processor to apply to the image.</param>
/// <returns>The <see cref="Image"/>.</returns>
internal static Image Process(this Image source, int width, int height, IImageSampler sampler)
public static Image Process(this Image source, int width, int height, IImageSampler sampler)
{
return Process(source, width, height, source.Bounds, default(Rectangle), sampler);
}
@ -102,8 +100,7 @@ namespace ImageProcessorCore
/// <summary>
/// Applies the collection of processors to the image.
/// <remarks>
/// This method does will resize the target image if the source and target
/// rectangles are different.
/// This method does will resize the target image if the source and target rectangles are different.
/// </remarks>
/// </summary>
/// <param name="source">The source image. Cannot be null.</param>
@ -120,9 +117,7 @@ namespace ImageProcessorCore
/// <returns>The <see cref="Image"/>.</returns>
public static Image Process(this Image source, int width, int height, Rectangle sourceRectangle, Rectangle targetRectangle, IImageSampler sampler)
{
source = PerformAction(source, false, (sourceImage, targetImage) => sampler.Apply(targetImage, sourceImage, width, height, targetRectangle, sourceRectangle));
return source;
return PerformAction(source, false, (sourceImage, targetImage) => sampler.Apply(targetImage, sourceImage, width, height, targetRectangle, sourceRectangle));
}
/// <summary>
@ -134,6 +129,11 @@ namespace ImageProcessorCore
/// <returns>The <see cref="Image"/>.</returns>
private static Image PerformAction(Image source, bool clone, Action<ImageBase, ImageBase> action)
{
if (source.IsDisposed)
{
throw new ObjectDisposedException("Image");
}
Image transformedImage = clone
? new Image(source)
: new Image
@ -165,9 +165,11 @@ namespace ImageProcessorCore
}
}
// Clean up.
source.Dispose();
return transformedImage;
// According to http://stackoverflow.com/questions/37921815/idisposable-unmanaged-fields-reference-types-and-assignments/37922955#37922955
// There's no need to dispose of the original image as the GC will get around to cleaning it up now there are no references to the original data.
// TODO: Investigate how log this is held onto and try to keep that to a minimum.
source = transformedImage;
return source;
}
}
}

36
tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs

@ -388,6 +388,42 @@
}
}
[Fact]
public void ImageShouldNotDispose()
{
if (!Directory.Exists("TestOutput/Dispose"))
{
Directory.CreateDirectory("TestOutput/Dispose");
}
foreach (string file in Files)
{
using (FileStream stream = File.OpenRead(file))
{
Stopwatch watch = Stopwatch.StartNew();
string filename = Path.GetFileName(file);
Image image = new Image(stream);
image = image.BackgroundColor(Color.RebeccaPurple);
using (FileStream output = File.OpenWrite($"TestOutput/Dispose/{filename}"))
{
ResizeOptions options = new ResizeOptions()
{
Size = new Size(image.Width - 200, image.Height),
Mode = ResizeMode.Stretch
};
image.Resize(options, this.ProgressUpdate)
.Save(output);
}
image.Dispose();
Trace.WriteLine($"{filename}: {watch.ElapsedMilliseconds}ms");
}
}
}
[Theory]
[MemberData("RotateFlips")]
public void ImageShouldRotateFlip(RotateType rotateType, FlipType flipType)

Loading…
Cancel
Save