문제

후에 몇 일을 추적의 기괴한 GDI+류,내가 우연히 발견이 작은 보석 on MSDN:

클래스 내에서 시스템입니다.그 네임스페이스가 지원되지 않 이내에 사용하거나 윈도우 ASP.NET 서비스입니다.를 사용하려고 하에서 이러한 클래스의 하나 이러한 응용 프로그램 형식을 예기치 않은 문제가 발생할 수 있습과 같은 서비스 성능이 저하되고 실시간 예외가 있습니다.

지 모르겠지만"ASP.NET 서비스"의"웹 응용 프로그램"이 상황에서,그러나"서비스 성능이 저하되"확실히 보을 커버하는 임의의 다양의"일반적인 오류가 발생한 GDI+"및"의 메모리"오류 내용을 던지-간헐적,재생할 수 없는 오류 읽기와 쓰기 JPEG 이미지는 많은 경우에-실제로에 의해 만들어 시스템입니다.Drawing.이미징에서 첫 번째 장소입니다.

그래서 경 GDI+읽고 쓸 수 없습 JPEG 파일을 안정적으로 웹앱에서 나는 무엇을 해야 될 사용하는 대신?

내가 원하는 사용자에게 이미지를 업로드(JPEG,필요한 다른 형식으면 좋겠다),그들 resample 안정적으로, 표시한 유용한 오류 메시지 오류가 발생하면 잘못입니다.어떤 아이디어가?는 시스템입니다.미디어 네임스페이스에서 WPF 고려 가치가?

편집: 그래,내가 알 GDI+작동하는"대부분의 시간".는 충분하지 않기 때문에,그것은 실패할 때,따라서 그것을 분리하거나 복구에서는 정상적입니다.제가 예 GDI+작동하는 코드 대신:내가 찾는 대체 라이브러리를 사용하여 이미지로 처리됩니다.

도움이 되었습니까?

해결책

이 우수한 블로그 게시물을 포함하여 C#코드를 사용에 대 ImageMagick 그래픽 라이브러리 을 통해 Interop 에서 이상 플러스 소프트웨어 블로그.이 게시물을 구체적으로 실행 ASP.net 리눅스에서 아래에는 모노;그러나,C#를 완벽하게 복사하여 붙여넣기할 수 있는 유일한 것을 변경해야 합니 Interop 특성을 실행하는 경우 윈도우에서 참조하는 창 바이너리(DLL)가 있습니다.

ImageMagick®소프트웨어 세트를 작성,편집,작성,변환 또는 비트맵 이미지입니다.읽고 쓸 수 있는 이미지에서는 다양한 형식 (100)포함 DPX,EXR,GIF,JPEG,JPEG-2000,PDF,PhotoCD, PNG,Postscript,SVG,TIFF.사용 ImageMagick 의 크기를 조정,flip, 거울,회전,왜곡,전단과 이미지 변환,이미지 조정 색상을 적용한 다양한 특수 효과에,또는 텍스트 그리기,선,다각형 타원 및 베지 곡선이 있습니다.

도 있습니다 ImageMagick.그물 개발 프로젝트 codeplex 의 래핑하는 모든 것을 당신을 위해.하지만 그것은 보이지 않는 개발이 활발하 2009,그래서 될 수 있습 뒤쳐 현재 ImageMagick 라이브러리 버전입니다.을 위한 작은 사소한 일상적인 크기를 조정하고,나는 아마 지팡이와 함께하시겠습니까?당신이해야하는 시계 당신의 구현을 주의깊게 자신의 메모리 누수 또는 출시되지 않은원(라이브러리 자체 테스트 및 심사에 의하여 커뮤니티).

라이브러리에는 무료 및 오픈 소스 소프트웨어입니다.아파치 2 라이센스타와 호환되는 개인 및 상업적 목적으로 합니다.보 ImageMagick 라이센스 페이지.

라이브러리가 완전히 크로스 플랫폼 구현하는 많은 강력한 이미지 처리 및 변환하는 루틴에서 발견되지 않은 GDI+(또는지 구현에노)에 있으로 좋은 평판을 대체한 ASP.net 이미지 처리합니다.

업데이트:처럼 보인 업데이트된 버전입니다.NET 래퍼 여기: http://magick.codeplex.com/

다른 팁

예, WPF를 사용하십시오 System.Windows.Media 클래스. 완전히 관리되면 GDI와 같은 문제를 겪지 않습니다.

다음은 그라디언트를 렌더링하는 데 사용하는 일부 MVC 코드의 발췌문입니다. WPF에서 얻는 방법을 알려줍니다. Visual PNG에 :

using System;
using System.IO;
using System.Web.Mvc;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace MyMvcWebApp.Controllers
{
    public class ImageGenController : Controller
    {
        // GET: ~/ImageGen/Gradient?color1=red&color2=pink
        [OutputCache(CacheProfile = "Image")]
        public ActionResult Gradient(Color color1, Color color2, int width = 1, int height = 30, double angle = 90)
        {
            var visual = new DrawingVisual();
            using (DrawingContext dc = visual.RenderOpen())
            {
                Brush brush = new LinearGradientBrush(color1, color2, angle);
                dc.DrawRectangle(brush, null, new Rect(0, 0, width, height));
            }

            return new FileStreamResult(renderPng(visual, width, height), "image/png");
        }

        static Stream renderPng(Visual visual, int width, int height)
        {
            var rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Default);
            rtb.Render(visual);

            var frame = BitmapFrame.Create(rtb);
            var encoder = new PngBitmapEncoder();
            encoder.Frames.Add(frame);

            var stream = new MemoryStream();
            encoder.Save(stream);
            stream.Position = 0;

            return stream;
        }
    }
}

Microsoft 직원의 아주 좋은 기사를 여기에서 찾을 수 있습니다. GDI+ 대신 WPF/WIC를 사용하여 서버에서 이미지 크기 조정 이는 GDI+대신 WPF를 사용하도록 제안합니다. 썸네일에 관한 것이지만 전반적으로 동일한 문제입니다.

어쨌든, 결국에는 다음과 같습니다.

WPF 팀에 연락하여 이것이 뒷받침되는지에 대한 최종 단어를 가지고있었습니다. 불행히도 그렇지 않으며 그에 따라 문서가 업데이트되고 있습니다. 이로 인해 발생한 혼란에 대해 사과드립니다. 우리는 미래에 그 이야기를 더 받아 들일 수있는 방법을 찾고 있습니다.

따라서 WPF는 웹 앱에도 지원되지 않지만 여전히 믿습니다 : -S

imagesharp

imagesharp 오픈 소스 크로스 플랫폼 2D 그래픽 라이브러리입니다. 새로운 .NET 표준 위에 C#으로 작성되었으며 OS 특이 적 API에 의존하지 않습니다.

현재 MYGET에 대한 사전 릴리스에 있습니다 (VS 옵션 또는 Nuget.config 파일에 패키지 소스를 추가해야 함). 그러나 우리는 이미 매우 긍정적 인 결과와 함께 사용하고 있습니다.

내가 읽은 대부분의 문제는 제대로 처분되지 않은 자원과 관련이 있습니다.

웹 응용 프로그램의 문제 없이이 코드의 변형을 시간과 시간을 다시 사용했습니다.

public void GenerateThumbNail(HttpPostedFile fil, string sPhysicalPath, 
                              string sOrgFileName,string sThumbNailFileName,
                              System.Drawing.Imaging.ImageFormat oFormat, int rez)
{

    try
    {

        System.Drawing.Image oImg = System.Drawing.Image.FromStream(fil.InputStream);

        decimal pixtosubstract = 0;
        decimal percentage;

        //default
        Size ThumbNailSizeToUse = new Size();
        if (ThumbNailSize.Width < oImg.Size.Width || ThumbNailSize.Height < oImg.Size.Height)
        {
            if (oImg.Size.Width > oImg.Size.Height)
            {
                percentage = (((decimal)oImg.Size.Width - (decimal)ThumbNailSize.Width) / (decimal)oImg.Size.Width);
                pixtosubstract = percentage * oImg.Size.Height;
                ThumbNailSizeToUse.Width = ThumbNailSize.Width;
                ThumbNailSizeToUse.Height = oImg.Size.Height - (int)pixtosubstract;
            }
            else
            {
                percentage = (((decimal)oImg.Size.Height - (decimal)ThumbNailSize.Height) / (decimal)oImg.Size.Height);
                pixtosubstract = percentage * (decimal)oImg.Size.Width;
                ThumbNailSizeToUse.Height = ThumbNailSize.Height;
                ThumbNailSizeToUse.Width = oImg.Size.Width - (int)pixtosubstract;
            }

        }
        else
        {
            ThumbNailSizeToUse.Width = oImg.Size.Width;
            ThumbNailSizeToUse.Height = oImg.Size.Height;
        }

        Bitmap bmp = new Bitmap(ThumbNailSizeToUse.Width, ThumbNailSizeToUse.Height);
        bmp.SetResolution(rez, rez);
        System.Drawing.Image oThumbNail = bmp;

        bmp = null;

        Graphics oGraphic = Graphics.FromImage(oThumbNail);

        oGraphic.CompositingQuality = CompositingQuality.HighQuality;

        oGraphic.SmoothingMode = SmoothingMode.HighQuality;

        oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;

        Rectangle oRectangle = new Rectangle(0, 0, ThumbNailSizeToUse.Width, ThumbNailSizeToUse.Height);

        oGraphic.DrawImage(oImg, oRectangle);

        oThumbNail.Save(sPhysicalPath  + sThumbNailFileName, oFormat);

        oImg.Dispose();

    }
    catch (Exception ex)
    {
        Response.Write(ex.Message);
    }

}

당신은 볼 수 있습니다 http://gd-sharp.sourceforge.net/ 이는 GD 라이브러리의 래퍼입니다. 나는 그것을 테스트하지 않았지만 유망한 것 같습니다.

ASP.NET 웹 서버 환경에서 카이로 도서관 (http://www.cairographics.org)에서 좋은 행동을 취했습니다. 웹 기반 물건에 대한 WPF의 메모리 사용 모델이 열악하기 때문에 실제로 WPF에서 카이로로 옮겼습니다.

WPF는 실제로 작업자 프로세스를 메모리에서 실행하는 경향이 있습니다. WPF 객체 중 어느 것도 구현되지 않았습니다 IDisposable, 그리고 그들 중 다수는 최종화기를 통해서만 해제되는 관리되지 않은 메모리를 참조합니다. WPF를 많이 사용합니다 (특히 서버가 크게 CPU 세액 인 경우)은 결국 파이널 라이저 큐가 포화되기 때문에 메모리를 제거합니다. 예를 들어 내 앱을 프로파일 링 할 때 마무리 대기열에는 5 만 개가 넘는 객체가 있었으며, 그 중 다수는 관리되지 않은 메모리에 대한 참조를 보유하고 있습니다. 카이로는 나에게 훨씬 더 잘 행동했으며 메모리 사용 패턴은 WPF보다 훨씬 예측 가능했습니다.

카이로 사용에 관심이 있으시면 GTK+의 웹 사이트에서 Libs를 잡으십시오. 그들은 x86과 x64 세트의 바이너리를 가지고 있습니다.

유일한 단점은 카이로가 JPG를 기본적으로 읽고 쓸 수 없다는 것입니다. 그러나 JPG를 읽고/쓰기 위해 WPF의 물건을 쉽게 적용하고 카이로를 사용하여 리샘플링/스케일링/드로잉/기타 작업을 수행 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top