web-dev-qa-db-fra.com

Redimensionner une image sans perdre de qualité

Je dois redimensionner une image, mais la qualité de l'image ne peut en être affectée.

104
public static

Comme rcar dit, vous ne pouvez pas perdre une partie de la qualité, le mieux que vous puissiez faire en c # est:

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

Sauf si vous réalisez des graphiques vectoriels, il est impossible de redimensionner une image sans perdre une partie de sa qualité.

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

de ici

24
ozba

Je crois que ce que vous cherchez à faire est de "redimensionner/rééchantillonner" vos images. Voici un bon site qui donne des instructions et fournit une classe d’utilitaires (que j’utilise aussi):

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

5
Ashlocke

Vous ne pouvez pas redimensionner une image sans perte de qualité, tout simplement parce que vous réduisez le nombre de pixels.

Ne réduisez pas la taille du côté client, car les navigateurs ne font pas un bon travail de redimensionnement des images.

Ce que vous pouvez faire est de modifier par programme la taille avant de la rendre ou lorsqu'un utilisateur la télécharge.

Voici un article qui explique comment procéder en c #: http://www.codeproject.com/KB/GDI-plus/imageresize.aspx

3
AaronS

Si vous ne redimensionnez pas, vous ne pouvez pas le faire avec des graphiques raster.

Avec un bon filtrage et un bon lissage, vous pouvez redimensionner sans perdre la qualité perceptible.

Vous pouvez également modifier les métadonnées DPI de l'image (en supposant qu'il en existe), ce qui conservera exactement le même nombre de pixels, mais modifiera la façon dont les éditeurs d'image en pensent dans des mesures "réelles".

Et juste pour couvrir toutes les bases, si vous voulez vraiment parler de la taille du fichier de l’image et non des dimensions réelles de l’image, je vous suggère d’envisager un codage sans perte des données de l’image. Ma suggestion serait de réenregistrer l'image sous forme de fichier .png (j'ai tendance à utiliser Paint comme transcodeur gratuit pour les images dans Windows. Chargez l'image dans Paint, enregistrez sous le nouveau format).

3
workmad3

Voyez si vous aimez la qualité qualité de redimensionnement de l'image de ce module ASP.NET open source. Il y a une démonstration en direct afin que vous puissiez vous amuser vous-même. Cela donne des résultats impossibles (à mon avis) à distinguer de la sortie Photoshop. La taille des fichiers est similaire - MS a bien travaillé sur son encodeur JPEG.

2
Nathanael Jones

Il y a quelque chose dehors, le redimensionnement conscient du contexte, je ne sais pas si vous pourrez l'utiliser, mais ça vaut la peine de regarder, c'est sûr

Une belle vidéo de démonstration (l'agrandissement apparaît vers le milieu) http://www.youtube.com/watch?v=vIFCV2spKtg

Ici, il pourrait y avoir du code. http://www.semanticmetadata.net/2007/08/30/content-aware-image-resizing-gpl-implementation/

Était-ce exagéré? Vous pouvez peut-être examiner certains filtres faciles à appliquer à une image agrandie pour rendre les pixels flous un peu.

1
Victor

Ici, vous pouvez également ajouter des codes de filigrane dans cette 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

Redimensionnez-vous plus grand ou plus petit? Par un petit pourcentage ou par un facteur plus important comme 2x, 3x? Qu'entendez-vous par qualité pour votre application? Et quel type d'images - des photographies, des dessins au trait aux contours nets, ou quoi? Écrire votre propre code de meulage de pixels de bas niveau ou essayer de le faire autant que possible avec des bibliothèques existantes (.net ou autre)?

Il existe un vaste corpus de connaissances sur ce sujet. Le concept clé est l'interpolation.

Recommandations de navigation:
* http://www.all-in-one.ee/~dersch/interpolator/interpolator.html
* http://www.cambridgeincolour.com/tutorials/image-interpolation.htm
* pour 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 * Ceci est spécifique à Java mais peut être éducatif - http://today.Java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance. html

1
DarenW

Voici un fil de discussion qui fournit un exemple de code de redimensionnement d'image C #. Vous pouvez utiliser l'un des classeurs Gd library pour effectuer le ré-échantillonnage en C #.

0
jimg