Goodmorning everyone。
我有以下问题:在MVC应用程序中,我创建了一个用于下载图像,缩放等的处理程序。它看起来工作正常,但在事件查看器中有些时候我收到错误,我不知道从哪里开始寻找甚至寻找解决方案。
错误:“操作成功完成。”它通过实例化“System.Windows.Media.Imaging.JpegBitmapEncoder”来实现
Exception information:
Exception type: Win32Exception
Exception message: The operation completed successfully
at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks)
at System.Windows.Threading.Dispatcher..ctor()
at System.Windows.Threading.DispatcherObject..ctor()
at System.Windows.Media.Imaging.BitmapEncoder..ctor(Boolean isBuiltIn)
at Totalcom.Drawing.ImageHelper.GetResizedImage(Byte[] bytes, Nullable`1 w, Nullable`1 h, Nullable`1 maxWidth, Nullable`1 maxHeight, Boolean keepRatio, Boolean crop, String backgroudColor, String imageFormat, Int32 dpi, Int32 quality)
更新:代码
/// <summary>
/// return byte of the resized image
/// </summary>
/// <param name="bytes">The bytes on original image.</param>
/// <param name="w">desidered width.</param>
/// <param name="h">desired height</param>
/// <param name="maxWidth">The maximum width.</param>
/// <param name="maxHeight">The maximum height.</param>
/// <param name="keepRatio">if set to <c>true</c> mantain ratio.</param>
/// <param name="crop">if set to <c>true</c> crop the resulting image.</param>
/// <param name="backgroudColor">Color of the backgroud.</param>
/// <param name="imageFormat">The image format.</param>
/// <param name="dpi">The dpi.</param>
/// <param name="quality">The quality.</param>
/// <returns></returns>
public static byte[] GetResizedImage(
byte[] bytes
, int? w
, int? h
, int? maxWidth
, int? maxHeight
, bool keepRatio
, bool crop
, string backgroudColor
, string imageFormat
, int dpi = 96
, int quality = 90
)
{
int width = w.HasValue && w > 0 ? w.Value : 0;
int height = h.HasValue && h > 0 ? h.Value : 0;
if (bytes.Length == 0)
{
return bytes;
}
Image img = null;
using (MemoryStream stream = new MemoryStream(bytes))
{
img = Image.FromStream(stream);
}
/* se ho specificato maxwidth o maxwidth, devo verificare se devo fare il resize o meno */
if (maxWidth.HasValue || maxHeight.HasValue)
{
/* verifico se devo fare il resize */
if (
(maxWidth.HasValue && img.Width < maxWidth)
||
(maxHeight.HasValue && img.Height < maxHeight)
)
{
return bytes;
}
else
{
if (maxWidth.HasValue && (maxWidth < width || width <= 0))
{
width = maxWidth.Value;
}
if (maxHeight.HasValue && (maxHeight < height || height <= 0))
{
height = maxHeight.Value;
}
}
}
if (img.IsAnimated())
{
/* prendo il primo frame */
img = img.GetFrame(0);
}
decimal resizeX = width;
decimal resizeY = height;
// Calcolo le dimensioni dell'immagine
/* Se non ho specificato altezza o largnezza, ma il ratio
* calcolo il parametro mancante*/
if (height > 0 & width <= 0 && keepRatio)
{
width = height * img.Width / img.Height;
resizeX = width;
}
else if (width > 0 & height <= 0 && keepRatio)
{
height = width * img.Height / img.Width;
resizeY = height;
}
else
{
/* crop
calcolo quale lato si deve adattare */
if (crop)
{
if ((decimal)img.Width / (decimal)width > (decimal)img.Height / (decimal)height)
{
resizeY = height;
resizeX = resizeY * img.Width / img.Height;
}
else
{
resizeX = width;
resizeY = resizeX * img.Height / img.Width;
}
}
else
{
if ((width * 100 / img.Width) < (height * 100 / img.Height))
{
// Se è più largo
resizeX = width;
resizeY = width * img.Height / img.Width;
}
else
{
// Se è più alto
resizeY = height;
resizeX = height * img.Width / img.Height;
}
}
}
int newW = width;
int newH = height;
if (keepRatio)
{
newW = (int)resizeX;
newH = (int)resizeY;
}
// Disegno l'immagine
using (Bitmap bmp = new Bitmap(width, height))
{
bmp.SetResolution(dpi, dpi);
Color c = Color.White;
if (imageFormat == CONTENT_TYPE_IMAGE_PNG)
{
c = Color.Transparent;
}
using (Graphics gr = Graphics.FromImage(bmp))
{
if (!String.IsNullOrEmpty(backgroudColor))
{
try
{
if (backgroudColor.Substring(0, 1) != "#")
{
backgroudColor = String.Format("#{0}", backgroudColor);
}
c = System.Drawing.ColorTranslator.FromHtml(backgroudColor);
}
catch { }
}
gr.Clear(c);
// Disegno l'immagine centrata
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
//gr.InterpolationMode = InterpolationMode.Bicubic;
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
gr.DrawImage(img, (width - newW) / 2, (height - newH) / 2, newW, newH);
}
// Salvo l'immagine nello stream
try
{
byte[] result = null;
using (MemoryStream m = new MemoryStream())
{
var codec = GetImageCodeInfo(imageFormat);
bmp.Save(m, GetImageCodeInfo(imageFormat), GetEncoderParameters(imageFormat));
result = m.GetBuffer();
}
BitmapEncoder targetEncoder;
if (imageFormat == CONTENT_TYPE_IMAGE_PNG)
{
targetEncoder = new PngBitmapEncoder()
{
};
}
else
{
targetEncoder = new JpegBitmapEncoder
{
QualityLevel = quality
};
}
var frame = ReadBitmapFrame(result);
var resize = FastResize(frame, width, height);
using (var memoryStream = new MemoryStream())
{
targetEncoder.Frames.Add(resize);
targetEncoder.Save(memoryStream);
result = memoryStream.ToArray();
}
targetEncoder = null;
frame = null;
resize = null;
GC.Collect();
GC.WaitForPendingFinalizers();
return result;
}
catch (System.Runtime.InteropServices.ExternalException)
{
//errore generico
//TODO : loggare l'errore
throw;
}
catch
{
throw;
}
}
}
public static BitmapFrame ReadBitmapFrame(byte[] bytes)
{
BitmapFrame result;
using (MemoryStream photoStream = new MemoryStream(bytes))
{
var photoDecoder = BitmapDecoder.Create(
photoStream,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.None);
result = photoDecoder.Frames[0];
}
return result;
}
public static BitmapFrame FastResize(BitmapFrame photo, int width, int height)
{
var target = new TransformedBitmap(
photo,
new System.Windows.Media.ScaleTransform(
width / photo.Width,
height / photo.Height,
0, 0));
return BitmapFrame.Create(target);
}