My jpeg are partially scrambled
-
Wednesday, January 18, 2012 10:03 AM
Sometimes I my jpegs are scrambled after some WIC resize using : BitmapScaler
Here is the broken one : http://hpics.li/e80665b or http://imageshack.us/photo/my-images/192/000par6782379b.jpg/
and the right one : http://hpics.li/6ccd09e or http://imageshack.us/photo/my-images/718/000par6782379.jpg/
I there something I'm doing wrong ?
The code is hosted in a WCF service, and working fine, could it be a thread safety problem ?
- Edited by Alex AxSoft Wednesday, January 18, 2012 10:06 AM links updated
All Replies
-
Friday, February 03, 2012 10:30 AM
Here is the code that reproduce the bug :(
My interop code come from this post : http://weblogs.asp.net/bleroy/archive/2010/05/03/the-fastest-way-to-resize-images-from-asp-net-and-it-s-more-supported-ish.aspx
Can someone tell me what is wrong ? I'm running a Win2008 R2, and should be in an MTA.
class Program { static void Main(string[] args) { Parallel.For(1, 200, c => { { Stream fStream = File.OpenRead("par6803327_2_1_0.jpg"); try { <span style="white-space:pre"> </span>Resize(new Size(170, 170), 94, 94, true, ref fStream); fStream.Position = 0; byte[] buffer = new byte[fStream.Length]; fStream.Read(buffer, 0, buffer.Length); if (buffer.Length < 20000) File.WriteAllBytes(".\\Out\\" + Path.GetRandomFileName() + ".wic.jpg", buffer); //else Thread.Sleep(05); } catch (Exception e) { File.WriteAllText(".\\Out\\" + Path.GetRandomFileName() + ".wic.log", e.ToString()); try { fStream.Position = 0; // Mdf.Medias.Tools.Transformations.WPF.TranformationsWPF.Resize( // new Size(170, 170), 94, 94, true, ref fStream); } catch (Exception ee) { File.WriteAllText(".\\Out\\" + Path.GetRandomFileName() + ".wpf.log", ee.ToString()); } byte[] buffer1 = new byte[fStream.Length]; fStream.Read(buffer1, 0, buffer1.Length); File.WriteAllBytes(".\\Out\\" + Thread.CurrentThread.ManagedThreadId + ".wpf.jpg", buffer1); //fStream.Position = 0; fStream = File.OpenRead("par6803327_2_1_0.jpg"); } // try { } }) ; return; } static readonly IWICComponentFactory factory = (IWICComponentFactory)new WICImagingFactory(); public static Size Resize(Size size, int quality, int compression, bool boxed, ref Stream outputContent, bool removeMetadata = false) { MemoryStream memoryStream = null; if (!(outputContent is MemoryStream)) { memoryStream = new MemoryStream(); outputContent.Position = 0; outputContent.CopyTo(memoryStream); outputContent = memoryStream; } else memoryStream = (MemoryStream)outputContent; memoryStream.Position = 0; IWICBitmapFrameDecode frame = null; // lock (lockResizeObject) { var inputStream = factory.CreateStream(); byte[] buffer = new byte[memoryStream.Length]; memoryStream.Position = 0; outputContent.Read(buffer, 0, buffer.Length); inputStream.InitializeFromMemory(buffer, (uint)buffer.Length); var decoder = factory.CreateDecoderFromStream(inputStream, null, WICDecodeOptions.WICDecodeMetadataCacheOnLoad); frame = decoder.GetFrame(0); } uint frameWidth = 0; uint frameHeight = 0; frame.GetSize(out frameWidth, out frameHeight); ////////// double heightRatio = (size.Height / (float)frameHeight); double widthRatio = (size.Width / (float)frameWidth); double ratio = Math.Min(heightRatio, widthRatio); double newWidth = 0; double newHeight = 0; if ((size.Height == frameHeight && size.Width >= frameWidth) || (size.Width == frameWidth && size.Height >= frameHeight)) { outputContent.Position = 0; return new Size((int)frameWidth, (int)frameHeight); } if ((!boxed && ratio == widthRatio) || (boxed && ratio == heightRatio)) { newWidth = size.Width; newHeight = (int)(newWidth / ((float)frameWidth / frameHeight)); } else { newHeight = size.Height; newWidth = (int)(newHeight * ((float)frameWidth / frameHeight)); } ////////// PropVariant metadataValue = null; if (!removeMetadata) { try { metadataValue = new PropVariant(); //Get All IPTC data frame.GetMetadataQueryReader().GetMetadataByName("/app13/irb/8bimiptc/iptc", metadataValue); } catch (Exception e) { //No metadata were available metadataValue = null; } } var outputStream = new MemoryIStream(); { // lock (lockResizeObject) { // Prepare JPG encoder var encoder = factory.CreateEncoder(Consts.GUID_ContainerFormatJpeg, null); encoder.Initialize(outputStream, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache); // Prepare output frame IWICBitmapFrameEncode outputFrame; var arg = new IPropertyBag2[1]; encoder.CreateNewFrame(out outputFrame, arg); var propBag = arg[0]; var propertyBagOption = new PROPBAG2[1]; propertyBagOption[0].pstrName = "ImageQuality"; propBag.Write(1, propertyBagOption, new object[] {(float) (quality == -1 ? 100 : quality)/100}); outputFrame.Initialize(propBag); outputFrame.SetResolution(96, 96); outputFrame.SetSize((uint) newWidth, (uint) newHeight); try { //Write previously retrieved IPTC data if (metadataValue != null) outputFrame.GetMetadataQueryWriter().SetMetadataByName("/app13/irb/8bimiptc/iptc", metadataValue); } catch (ArgumentException) { //Value does not fall within the expected range. //:( unknown exception and don't know how to solve this //Maybe metadata is not so important } // Prepare scaler var scaler = factory.CreateBitmapScaler(); scaler.Initialize(frame, (uint) newWidth, (uint) newHeight, WICBitmapInterpolationMode.WICBitmapInterpolationModeCubic); // Write the scaled source to the output frame outputFrame.WriteSource(scaler, new WICRect {X = 0, Y = 0, Width = (int) newWidth, Height = (int) newHeight}); outputFrame.Commit(); encoder.Commit(); } //outputContent.Position = 0; //outputStream.Position = 0; outputContent = outputStream; outputContent.Position = 0; //outputStream.Close(); return new Size((int)newWidth, (int)newHeight); } } }
-
Wednesday, February 15, 2012 3:21 PM
Here is the same problem with simplified code :
static void Main(string[] args) { Parallel.For(1, 300, new ParallelOptions(){MaxDegreeOfParallelism = 8}, c => { Stream fStream = File.OpenRead("par6803327_2_1_0.jpg"); try { Stream res = Mdf.Medias.Tools.Transformations.WIC.TranformationsWIC.Test( new Size(170, 170), 94, 94, true, fStream); fStream.Position = 0; byte[] buffer = new byte[res.Length]; res.Read(buffer, 0, buffer.Length); //if (buffer.Length < 21000) File.WriteAllBytes(".\\Out\\" + Path.GetRandomFileName() + ".wic.jpg", buffer); //else Thread.Sleep(05); } catch (Exception e) { File.WriteAllText(".\\Out\\" + Path.GetRandomFileName() + ".wic.log", e.ToString()); } }) ; return; }
public static Stream Test(Size size, int quality, int compression, bool boxed, Stream outputContent, bool removeMetadata = false) { MemoryIStream memoryStream = null; if (!(outputContent is MemoryStream)) { memoryStream = new MemoryIStream(); outputContent.Position = 0; outputContent.CopyTo(memoryStream); outputContent = memoryStream; } else memoryStream = (MemoryIStream)outputContent; IWICBitmapFrameDecode frame = null; IWICBitmapDecoder decoder = null; IWICComponentFactory factory2 = (IWICComponentFactory)new WICImagingFactory(); var inputStream = factory2.CreateStream(); memoryStream.Position = 0; inputStream.InitializeFromMemory(memoryStream.ToArray(), (uint)memoryStream.Length); decoder = factory2.CreateDecoderFromStream(inputStream, null, WICDecodeOptions.WICDecodeMetadataCacheOnLoad); frame = decoder.GetFrame(0); using(var outputStream = new MemoryIStream()) { // Prepare JPG encoder var encoder = factory2.CreateEncoder(Consts.GUID_ContainerFormatJpeg, null); encoder.Initialize(outputStream, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache); // Prepare output frame IWICBitmapFrameEncode outputFrame; var arg = new IPropertyBag2[0]; encoder.CreateNewFrame(out outputFrame, arg); outputFrame.Initialize(null); outputFrame.WriteSource(frame, null); outputFrame.Commit(); encoder.Commit(); Marshal.ReleaseComObject(inputStream); Marshal.ReleaseComObject(outputFrame); Marshal.ReleaseComObject(frame); Marshal.ReleaseComObject(encoder); Marshal.ReleaseComObject(decoder); Marshal.ReleaseComObject(factory2); Marshal.CleanupUnusedObjectsInCurrentContext(); var array = outputStream.ToArray(); return new MemoryStream(array); } }The output is correct about 80% of time, but sometimes its corrupted like these.
Can someone confirm that on other computers ? and maybe tell me what's wrong with this code ?
- Edited by Alex AxSoft Wednesday, February 15, 2012 3:22 PM
-
Monday, February 20, 2012 11:19 AM
Proxy methods are the answer to this problem- Marked As Answer by Alex AxSoft Monday, February 20, 2012 11:19 AM


