Frage

Nach mehreren Tagen, in denen bizarre GDI+ -Anfehler aufgespürt wurden, bin ich über dieses kleine Juwel gestolpert Msdn:

Klassen innerhalb des Systems. Der Versuch, diese Klassen innerhalb eines dieser Anwendungstypen aus zu verwenden, kann unerwartete Probleme verursachen, wie z. B. verringerte Serviceleistung und Laufzeitausnahmen.

Ich weiß nicht, ob "ASP.NET Service" in diesem Zusammenhang "Webanwendung" bedeutet, aber "verringerte Serviceleistung" scheint das zufällige Sortiment von "Ein generischer Fehler in GDI+" und "Out -Memory" -Fehlern zu behandeln. Dass meine App zeitweise, nicht reproduzierbare Fehler lesen und schreiben, die JPEG -Bilder lesen und schreiben, die - in vielen Fällen - tatsächlich durch System erstellt wurden.

Also - wenn GDI+ JPEG -Dateien in einer Web -App nicht zuverlässig lesen und schreiben kann, was sollte ich stattdessen verwenden?

Ich möchte, dass Benutzer Bilder hochladen können (JPEG erforderlich, andere Formate schön zu haben), sie wiederzuproben zuverlässig, und zeigen nützliche Fehlermeldungen an, wenn etwas schief geht. Irgendwelche Ideen? Sind das System.Media Namespaces von WPF es wert?

BEARBEITEN: Ja, ich weiß, dass GDI+ die meiste Zeit "die meiste Zeit" funktioniert. Das ist nicht gut genug, denn wenn es fehlschlägt, ist dies auf eine Weise, die unmöglich ist, anmutig zu isolieren oder sich zu erholen. Ich interessiere mich nicht für Beispiele für GDI+ -Codes, die für Sie funktioniert: Ich suche nach Alternative Bibliotheken für die Bildverarbeitung.

War es hilfreich?

Lösung

Es gibt einen exzellenten Blog -Beitrag mit C# -Codes über die Verwendung der Verwendung Imagemagick Graphics Library durch Interop vorbei bei Topten Software -Blog. Dieser Beitrag befasst sich speziell mit dem Ausführen von ASP.NET unter Linux unter Mono; Der C# -Codel sollte jedoch perfekt kopieren.

Imagemagick® ist eine Software -Suite zum Erstellen, Bearbeiten, Komponieren oder Konvertieren von Bitmap -Bildern. Es kann Bilder in einer Vielzahl von Formaten (über 100) einschließlich DPX, EXR, GIF, JPEG, JPEG-2000, PDF, Photocd, PNG, Postscript, SVG und TIFF lesen und schreiben. Verwenden Sie Imagemagick, um die Größe zu ändern, zu überfliegen, zu spiegeln, zu drehen, zu verzerren, Bilder zu scheren und zu transformieren, Bildfarben einzustellen, verschiedene Spezialeffekte anzuwenden oder Text, Linien, Polygone, Ellipsen und Bézier -Kurven zu zeichnen.

Es gibt auch eine ImageMagick .NET -Entwicklungsprojekt Auf Codeplex, das alles für Sie abschließt. Aber es zeigt seit 2009 keine aktive Entwicklung, daher kann es hinter der aktuellen ImageMagick -Bibliotheksversion zurückbleiben. Für eine kleine triviale Änderungsroutine würde ich wahrscheinlich an die Interop bleiben. Sie müssen Ihre Implementierung nur sorgfältig nach Ihrem eigenen Speicherleck oder unveröffentlichten Ressourcen beobachten (die Bibliothek selbst wird von der Community gut getestet und überprüft).

Die Bibliothek ist kostenlos und Open Source. Die Apache 2 -Lizenz scheint sowohl mit persönlichen als auch mit kommerziellen Zwecken kompatibel zu sein. Sehen Bildemagick -Lizenzseite.

Die Bibliothek ist eine vollständige Kreuzplattform und implementiert viele leistungsstarke Bild- und Transformationsroutinen, die in GDI+ (oder nicht unter Mono implementiert sind) und haben einen guten Ruf als Alternative für die ASP.NET -Bildverarbeitung.

UPDATE: Sieht so aus, als ob hier eine aktualisierte Version eines .NET -Wrappers gibt: http://magick.codeplex.com/

Andere Tipps

Ja, verwenden Sie den WPF System.Windows.Media Klassen. Wenn sie vollständig verwaltet werden, leiden sie nicht als die gleichen Probleme wie das GDI -Zeug.

Hier ist ein Auszug aus einem MVC -Code, den ich verwende, um Gradienten zu rendern, um Ihnen eine Idee zu geben, wie Sie von einem WPF bekommen können Visual zu einem 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;
        }
    }
}

Hier finden Sie einen sehr guten Artikel von einem Microsoft -Mitarbeiter hier: Größen Sie die Größe von Bildern vom Server mit WPF/WIC anstelle von GDI+ Dies schlägt vor, WPF anstelle von GDI+zu verwenden. Es geht mehr um Miniaturansicht, aber insgesamt ist es die gleichen Probleme.

Wie auch immer, am Ende heißt es Folgendes:

Ich habe das WPF -Team kontaktiert, um das letzte Wort darüber zu haben, ob dies unterstützt wird. Leider ist es nicht und die Dokumentation wird entsprechend aktualisiert. Ich entschuldige mich für Verwirrung, die dies möglicherweise verursacht hat. Wir suchen nach Möglichkeiten, diese Geschichte in Zukunft akzeptabler zu machen.

WPF ist also auch in Web-Apps nicht unterstützt und glaube ich immer noch: -S

Imagesharp

Imagesharp ist eine Open-Source-plattformübergreifende 2D-Grafikbibliothek. Es ist in C# über dem neuen .NET-Standard geschrieben, ohne von einer OS-spezifischen API abhängig zu sein.

Es befindet sich derzeit noch in Myget vorab (Sie müssen die Paketquelle in die VS-Optionen oder eine Nuget.config-Datei hinzufügen), aber wir verwenden sie bereits mit einigen sehr positiven Ergebnissen.

Die meisten Probleme, über die ich gelesen habe, beziehen sich auf Ressourcen, die nicht ordnungsgemäß entsorgt werden.

Ich habe Varianten dieser Code immer wieder ohne Probleme aus Webanwendungen verwendet:

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);
    }

}

Sie können sich ansehen http://gd-sharp.sourceforge.net/ Das ist ein Wrapper für die GD -Bibliothek. Ich habe es nicht getestet, aber es scheint vielversprechend.

Ich hatte in einer ASP.NET -Webserver -Umgebung gutes Verhalten in der Cairo -Bibliothek (http://www.cairographics.org). Ich bin tatsächlich von WPF nach Kairo gezogen, weil das schlechte Speicherverbrauchsmodell von WPF für webbasierte Dinge.

WPF neigt dazu, Ihren Arbeitsprozess aus dem Gedächtnis zu führen. Keiner der WPF -Objekte implementieren IDisposable, und viele von ihnen verweisen auf ein nicht verwaltetes Gedächtnis, das nur über einen Finalizer befreit wird. Die starke Verwendung von WPF (insbesondere wenn Ihr Server erheblich von CPU gesteuert ist) wird Sie schließlich aus dem Speicher ausführen, da Ihre Finalizer-Warteschlange gesättigt wird. Als ich beispielsweise meine App profilierte, hatte die Finalization -Warteschlange über 50.000 Objekte, von denen viele Hinweise auf nicht verwaltetes Speicher hielten. Kairo hat sich für mich viel besser verhalten und sein Gedächtnisnutzungsmuster war viel vorhersehbarer als die von WPF.

Wenn Sie an Kairo interessiert sind, nehmen Sie die LIBS von der Website von GTK+. Sie haben einen x86 sowie einen x64 -Binärdatmen.

Der einzige Nachteil ist, dass Kairo JPG nativ nicht lesen/schreiben kann; Sie können jedoch leicht WPF -Sachen für das Lesen/Schreiben von JPG anpassen und das Resampling/Skalieren/Zeichnen/was auch immer mit Kairo durchführen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top