When comparing two images in my project I often get an AccessViolationException from MagickImage.Compare(MagickImage).
I've validated that both of the MagickImages are not null, and are populated.
This error is occasionally thrown on my dev machine (Win 7 64bit) in both Debug & Release. On the deployment machine (Win Server 2012 R2 64bit), it is thrown consistently.
This is the code flow for the comparison:
First I load the images from the drive
DefaultImage is a 1x1 white pixel that is loaded into the project through C#'s Resource Manager, under the project's Properties > Resources.resx file. Class file is using the appropriate "using namespace.Properties".
I then execute the comparison:
The first compare "Error = Actual.Image.Compare(Expected.Image);" is where I'm running into the Access Violation.
Below is the stack trace & additional Event Viewer fault information from my deployment machine:
At this point, I've exhausted everything I can thing of to try and fix this.
Please let me know if any additional information would be helpful.
I've validated that both of the MagickImages are not null, and are populated.
This error is occasionally thrown on my dev machine (Win 7 64bit) in both Debug & Release. On the deployment machine (Win Server 2012 R2 64bit), it is thrown consistently.
This is the code flow for the comparison:
First I load the images from the drive
///<summary>/// Load in images so that a comparison can be done///</summary>publicvoid LoadImages() { Expected.LoadImage(@"c:\"); Actual.LoadImage(@"c:\"); Comparison.LoadImage(""); } ///<summary>/// Update the image using location///</summary>publicvoid LoadImage(string drive) { if(!String.IsNullOrWhiteSpace(drive + Location) && File.Exists(drive + Location)) { Image = new MagickImage(drive + Location); } else { Image = new MagickImage(Resources.DefaultImage); } }
I then execute the comparison:
///<summary>/// Compare the actual to the expected with resulting comparison image and error info///</summary>publicvoid Compare() { Error = Actual.Image.Compare(Expected.Image); Actual.Image.Compare(Expected.Image, ErrorMetric.Fuzz, Comparison.Image); }
Below is the stack trace & additional Event Viewer fault information from my deployment machine:
Application: ProjectName.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
Stack:
at <Module>.Magick.Image.compare(Magick.Image*, Magick.Image*)
at <Module>.Magick.Image.compare(Magick.Image*, Magick.Image*)
at ImageMagick.MagickImage.Compare(ImageMagick.MagickImage)
at DynamicClass.invoke(System.Object, System.Object[])
at ImageMagick.MagickImage.Compare(ImageMagick.MagickImage)
at Namespace.ImageCompare.Compare()
at Namespace.Compare+<>c__DisplayClass2.<CompareImages>b__0()
at Namespace.TestResult.CaptureException(System.Action)
at Namespace.Compare.CompareImages()
at Namespace.ProjectName.Main(System.String[])
Faulting application name: ProjectName.exe, version: 1.0.0.0, time stamp: 0x54eceeb4
Faulting module name: Magick.NET-Q16-x64.dll, version: 7.0.0.9, time stamp: 0x54c6b9b9
Exception code: 0xc0000005
Fault offset: 0x000000000018337d
Faulting process id: 0x2a4
Faulting application start time: 0x01d050838806959c
Faulting application path: D:\ProjectName\ProjectName.exe
Faulting module path: C:\Users\user\AppData\Local\Temp\Magick.NET.7.0.0.0009\Magick.NET-Q16-x64.dll
Report Id: 2bd78f71-bc79-11e4-80ea-069bf534f868
Faulting package full name:
Faulting package-relative application ID:
The compare is passed through a delegate to capture any exceptions in a try/catch, but this one manages to still break execution.///<summary>/// Used to encapsulate tests in a try catch and log any exceptions///</summary>///<param name="action">The Method to wrap in a try/catch</param>///<returns>True: Action was completed without issue.</returns>///<returns>False: An exception was encountered and logged.</returns>publicbool CaptureException(Action action) { try { action(); } catch(Exception exception) { ExceptionMessage.Add(exception.Message); StackTrace.Add(exception.StackTrace); returnfalse; } returntrue; } ///<summary>/// Compare the images in each TestResult///</summary>publicvoid CompareImages() { foreach(TestResult testResult in testResults) { testResult.CaptureException( () => { testResult.Images.LoadImages(); testResult.Images.Compare(); // Do other things ... testResult.Images.UnloadImages(); }); } }
Please let me know if any additional information would be helpful.