c# - Alternative a System.Drawing per l'utilizzo con ASP.NET?





gdi+ system.drawing.imaging (7)


Sì, usa le classi WPF System.Windows.Media . Essendo completamente gestiti non subiscono gli stessi problemi del materiale GDI.

Ecco un estratto da un codice MVC che utilizzo per il rendering dei gradienti, per darti un'idea di come ottenere da un Visual FoxPro in 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;
        }
    }
}

Dopo diversi giorni di rintracciare gli errori bizzarri di GDI +, mi sono imbattuto in questo piccolo gioiello su MSDN :

Le classi all'interno dello spazio dei nomi System.Drawing non sono supportate per l'uso all'interno di un servizio Windows o ASP.NET. Il tentativo di utilizzare queste classi all'interno di uno di questi tipi di applicazioni può causare problemi imprevisti, ad esempio la riduzione delle prestazioni del servizio e le eccezioni di run-time.

Non so se "servizio ASP.NET" significa "applicazione web" in questo contesto, ma "prestazioni di servizio ridotte" sembrano certamente coprire l'assortimento casuale di errori "Errore generico verificatosi in GDI +" e "Memoria insufficiente" che la mia app sta lanciando - errori intermittenti e non riproducibili che leggono e scrivono immagini JPEG che in molti casi sono state effettivamente create da System.Drawing.Imaging in primo luogo.

Quindi, se GDI + non è in grado di leggere e scrivere file JPEG in modo affidabile in un'app Web, cosa dovrei usare invece?

Voglio che gli utenti siano in grado di caricare immagini (necessario JPEG, altri formati piacevoli), ricampionarli in modo affidabile e visualizzare utili messaggi di errore se qualcosa va storto. Qualche idea? Vale la pena considerare gli spazi dei nomi System.Media di WPF?

Grazie,

Dylan

EDIT: Sì, so che GDI + funziona "il più delle volte". Non è abbastanza buono, perché quando fallisce, lo fa in un modo che è impossibile isolare o recuperare con garbo. Non sono interessato ad esempi di codice GDI + che funzionano per te: sto cercando librerie alternative da utilizzare per l'elaborazione delle immagini.




È possibile trovare un ottimo articolo da un dipendente Microsoft qui: Ridimensionamento delle immagini dal server utilizzando WPF / WIC anziché GDI + che propone di utilizzare WPF anziché GDI +. È più una questione di miniature, ma nel complesso sono gli stessi problemi.

Ad ogni modo, alla fine afferma questo:

Ho contattato il team WPF per avere l'ultima parola sul fatto che questo sia supportato. Sfortunatamente, non lo è, e la documentazione viene aggiornata di conseguenza. Mi scuso per l'eventuale confusione che ciò potrebbe aver causato. Stiamo cercando modi per rendere questa storia più accettabile in futuro.

Quindi WPF non è supportato nelle app Web e credo ancora: -S







Ho avuto un buon comportamento dalla biblioteca del Cairo (http://www.cairographics.org) in un ambiente web server ASP.Net. In realtà mi sono trasferito a cairo da WPF a causa del povero modello di utilizzo della memoria di WPF per roba basata sul web.

WPF tende in realtà a far uscire il processo di lavoro dalla memoria. Nessuno degli oggetti WPF implementa IDisposable e molti di essi fanno riferimento alla memoria non gestita liberata solo tramite un finalizzatore. L'uso intensivo di WPF (specialmente se il tuo server è soggetto a tassazione della CPU) alla fine ti farà esaurire la memoria perché la coda del finalizzatore diventa satura. Quando stavo profilando la mia app, ad esempio, la coda di finalizzazione conteneva più di 50.000 oggetti, molti dei quali contengono riferimenti alla memoria non gestita. Il Cairo si è comportato molto meglio per me e il suo schema di utilizzo della memoria è stato molto più prevedibile di quello di WPF.

Se sei interessato a usare cairo, prendi le librerie dal sito web di GTK +. Hanno un x86 e un insieme di binari x64.

L'unico lato negativo è che cairo non può leggere / scrivere JPG in modo nativo; tuttavia, è possibile adattare facilmente le cose di WPF per la lettura / scrittura di JPG e fare il resampling / ridimensionamento / disegno / qualsiasi altra cosa usando Cairo.




C'è un eccellente post sul blog che include il codice C # sull'utilizzo della libreria grafica ImageMagick tramite Interop su TopTen Software Blog . Questo post riguarda specificamente l'esecuzione di ASP.net su linux in mono; tuttavia, il codice C # dovrebbe essere perfettamente copia-incollabile, l'unica cosa che dovrai modificare sono gli attributi Interop se stai usando Windows che fa riferimento a una finestra binaria (DLL).

ImageMagick® è una suite software per creare, modificare, comporre o convertire immagini bitmap. Può leggere e scrivere immagini in una varietà di formati (oltre 100) inclusi DPX, EXR, GIF, JPEG, JPEG-2000, PDF, PhotoCD, PNG, Postscript, SVG e TIFF. Usa ImageMagick per ridimensionare, capovolgere, specchiare, ruotare, distorcere, tagliare e trasformare le immagini, regolare i colori dell'immagine, applicare vari effetti speciali o disegnare testo, linee, poligoni, ellissi e curve di Bézier.

C'è anche un progetto di sviluppo ImageMagick .Net su codeplex che racchiude tutto per te. Ma non mostra lo sviluppo attivo dal 2009, quindi potrebbe essere in ritardo rispetto alla versione corrente della libreria ImageMagick. Per una piccola routine di ridimensionamento banale, probabilmente starei con l'interoperabilità. Hai solo bisogno di osservare attentamente la tua implementazione per la tua perdita di memoria o risorse inedite (la stessa libreria è ben testata e controllata dalla comunità).

La biblioteca è gratuita e open source. La licenza di Apache 2 sembra essere compatibile sia con scopi personali che commerciali. Vedi la pagina della licenza di ImageMagick .

La libreria è totalmente multipiattaforma e implementa molte potenti routine di gestione e trasformazione delle immagini che non si trovano in GDI + (o non implementate in mono) e ha una buona reputazione come alternativa per l'elaborazione delle immagini ASP.net.

Aggiornamento: sembra che ci sia una versione aggiornata di un wrapper .NET qui: http://magick.codeplex.com/




ImageSharp

ImageSharp è una libreria grafica 2D multipiattaforma open source. È scritto in C # in cima al nuovo standard .NET, senza alcuna dipendenza da API specifiche del sistema operativo.

Al momento è ancora in pre-release su MyGet (dovrai aggiungere la fonte del pacchetto nelle opzioni VS o in un file NuGet.config), ma lo stiamo già utilizzando con risultati molto positivi.




In IgnoreRoute , hai specificato la cartella "Contenuto". Prova anche ad aggiungerne uno per i caratteri ", poiché è ciò che stai richiedendo.

routes.IgnoreRoute("{folder}/{*pathInfo}", new { folder = "fonts" });




c# asp.net gdi+ system.drawing system.drawing.imaging