it-swarm-eu.dev

Ridimensionare un'immagine senza perdere la qualità

Devo ridimensionare un'immagine, ma la qualità dell'immagine non può essere influenzata da questo.

104
public static

Come rcar dice, non puoi fare a meno di perdere un po 'di qualità, il meglio che puoi fare in c # è:

Bitmap newImage = new Bitmap(newWidth, newHeight);
using (Graphics gr = Graphics.FromImage(newImage))
{
    gr.SmoothingMode = SmoothingMode.HighQuality;
    gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
    gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
    gr.DrawImage(srcImage, new Rectangle(0, 0, newWidth, newHeight));
}
211
Kris Erickson

A meno che tu non stia facendo grafica vettoriale, non c'è modo di ridimensionare un'immagine senza potenzialmente perdere una certa qualità dell'immagine.

32
Randy
private static Image resizeImage(Image imgToResize, Size size)
{
    int sourceWidth = imgToResize.Width;
    int sourceHeight = imgToResize.Height;

    float nPercent = 0;
    float nPercentW = 0;
    float nPercentH = 0;

    nPercentW = ((float)size.Width / (float)sourceWidth);
    nPercentH = ((float)size.Height / (float)sourceHeight);

    if (nPercentH < nPercentW)
        nPercent = nPercentH;
    else
        nPercent = nPercentW;

    int destWidth = (int)(sourceWidth * nPercent);
    int destHeight = (int)(sourceHeight * nPercent);

    Bitmap b = new Bitmap(destWidth, destHeight);
    Graphics g = Graphics.FromImage((Image)b);
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;

    g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
    g.Dispose();

    return (Image)b;
}

da qui

24
ozba

Credo che ciò che stai cercando di fare sia "Ridimensiona/Ricampiona" le tue immagini. Ecco un buon sito che fornisce istruzioni e fornisce una classe di utilità (che mi capita anche di usare):

http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx

5
Ashlocke

Non puoi ridimensionare un'immagine senza perdere un po 'di qualità, semplicemente perché stai riducendo il numero di pixel.

Non ridurre le dimensioni del lato client, perché i browser non fanno un buon lavoro di ridimensionamento delle immagini.

Quello che puoi fare è modificare programmaticamente la dimensione prima di renderizzarla o quando un utente la carica.

Ecco un articolo che spiega un modo per farlo in c #: http://www.codeproject.com/KB/GDI-plus/imageresize.aspx

3
AaronS

A meno che non si ridimensioni, non è possibile farlo con la grafica raster.

Quello che puoi fare con un buon filtro e smoothing è ridimensionare senza perdere la qualità evidente.

Puoi anche modificare i metadati DPI dell'immagine (supponendo che ne abbia alcuni) che manterranno esattamente lo stesso numero di pixel, ma altereranno il modo in cui gli editor di immagini la pensano in misurazioni del "mondo reale".

E solo per coprire tutte le basi, se intendevi davvero solo la dimensione del file dell'immagine e non le dimensioni effettive dell'immagine, ti suggerisco di guardare una codifica senza perdita di dati dell'immagine. Il mio suggerimento per questo sarebbe di salvare nuovamente l'immagine come file .png (tendo ad usare Paint come transcoder gratuito per le immagini in Windows. Carica l'immagine in Paint, salva come nel nuovo formato)

3
workmad3

Vedi se ti piace qualità di ridimensionamento delle immagini di questo modulo ASP.NET open source. C'è una demo live, quindi puoi scherzare con te stesso. Produce risultati che (per me) sono impossibili da distinguere dall'output di Photoshop. Ha anche dimensioni di file simili: MS ha fatto un buon lavoro sul suo codificatore JPEG.

2
Nathanael Jones

C'è qualcosa là fuori, ridimensionamento consapevole del contesto, non so se sarai in grado di usarlo, ma vale la pena guardarlo, questo è sicuro

Una bella demo video (Ingrandimento appare verso il centro) http://www.youtube.com/watch?v=vIFCV2spKtg

Qui potrebbe esserci del codice. http://www.semanticmetadata.net/2007/08/30/content-aware-image-resizing-gpl-implementation/

Era eccessivo? Forse ci sono alcuni filtri facili che puoi applicare a un'immagine ingrandita per sfocare un po 'i pixel, potresti esaminarli.

1
Victor

Qui puoi anche aggiungere i codici filigrana in questa classe:

public class ImageProcessor
    {
        public Bitmap Resize(Bitmap image, int newWidth, int newHeight, string message)
        {
            try
            {
                Bitmap newImage = new Bitmap(newWidth, Calculations(image.Width, image.Height, newWidth));

                using (Graphics gr = Graphics.FromImage(newImage))
                {
                    gr.SmoothingMode = SmoothingMode.AntiAlias;
                    gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    gr.DrawImage(image, new Rectangle(0, 0, newImage.Width, newImage.Height));

                    var myBrush = new SolidBrush(Color.FromArgb(70, 205, 205, 205));

                    double diagonal = Math.Sqrt(newImage.Width * newImage.Width + newImage.Height * newImage.Height);

                    Rectangle containerBox = new Rectangle();

                    containerBox.X = (int)(diagonal / 10);
                    float messageLength = (float)(diagonal / message.Length * 1);
                    containerBox.Y = -(int)(messageLength / 1.6);

                    Font stringFont = new Font("verdana", messageLength);

                    StringFormat sf = new StringFormat();

                    float slope = (float)(Math.Atan2(newImage.Height, newImage.Width) * 180 / Math.PI);

                    gr.RotateTransform(slope);
                    gr.DrawString(message, stringFont, myBrush, containerBox, sf);
                    return newImage;
                }
            }
            catch (Exception exc)
            {
                throw exc;
            }
        }

        public int Calculations(decimal w1, decimal h1, int newWidth)
        {
            decimal height = 0;
            decimal ratio = 0;


            if (newWidth < w1)
            {
                ratio = w1 / newWidth;
                height = h1 / ratio;

                return height.To<int>();
            }

            if (w1 < newWidth)
            {
                ratio = newWidth / w1;
                height = h1 * ratio;
                return height.To<int>();
            }

            return height.To<int>();
        }

    }
1
cagin

Stai ridimensionando più grande o più piccolo? Di una piccola% o di un fattore maggiore come 2x, 3x? Cosa intendi per qualità per la tua applicazione? E che tipo di immagini - fotografie, disegni a tratteggio duro o cosa? Stai scrivendo il tuo codice di macinatura di pixel di basso livello o stai provando a farlo il più possibile con le librerie esistenti (.net o altro)?

C'è un ampio corpus di conoscenze su questo argomento. Il concetto chiave è l'interpolazione.

Consigli per la navigazione:
* http://www.all-in-one.ee/~dersch/interpolator/interpolator.html
* http://www.cambridgeincolour.com/tutorials/image-interpolation.htm
* per C #: https://secure.codeproject.com/KB/GDI-plus/imageprocessing4.aspx?display=PrintAll&fid=3657&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26&select = 629945 * questo è specifico di Java ma potrebbe essere educativo - http://today.Java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance. html

1
DarenW

Ecco un thread del forum che fornisce un esempio di codice per il ridimensionamento dell'immagine C #. Puoi usare uno dei leganti Gd library per fare il ricampionamento in C #.

0
jimg