Erstellen Sie ein Miniaturbild

96

Ich möchte ein Miniaturbild in einer Rasteransicht vom Speicherort der Datei anzeigen. Wie generiere ich die .jpegDatei? Ich benutze C#Sprache mit asp.net.

Roter Schwan
quelle
6
ImageResizer ist eine serverseitige Bibliothek, die genau das tut, was Sie benötigen. Im Gegensatz zu GetThumbnailImage werden qualitativ hochwertige Ergebnisse erzielt, und im Gegensatz zu den Codebeispielen wird kein Speicher wie bei einem Sieb verloren. Es ist dir jetzt vielleicht egal, aber du wirst es in ein paar Monaten tun, wenn du knietief in Core Dumps bist.
Lilith River
Sehen Sie dies: docs.microsoft.com/en-us/dotnet/api/…
Md. Sabbir Ahamed
ImageResizer ist großartig, aber nicht kostenlos
Boban Stojanovski

Antworten:

222

Sie müssen die GetThumbnailImageMethode in der ImageKlasse verwenden:

https://msdn.microsoft.com/en-us/library/8t23aykb%28v=vs.110%29.aspx

Hier ist ein grobes Beispiel, bei dem eine Bilddatei aus einem Miniaturbild erstellt und anschließend wieder auf der Festplatte gespeichert wird.

Image image = Image.FromFile(fileName);
Image thumb = image.GetThumbnailImage(120, 120, ()=>false, IntPtr.Zero);
thumb.Save(Path.ChangeExtension(fileName, "thumb"));

Es befindet sich im System.Drawing-Namespace (in System.Drawing.dll).

Verhalten:

Wenn das Bild ein eingebettetes Miniaturbild enthält, ruft diese Methode das eingebettete Miniaturbild ab und skaliert es auf die angeforderte Größe. Wenn das Bild kein eingebettetes Miniaturbild enthält, erstellt diese Methode ein Miniaturbild, indem das Hauptbild skaliert wird.


Wichtig: Der Abschnitt mit den Anmerkungen des obigen Microsoft-Links warnt vor bestimmten potenziellen Problemen:

Die GetThumbnailImageMethode funktioniert gut, wenn das angeforderte Miniaturbild eine Größe von ca. 120 x 120 Pixel hat. Wenn Sie ein großes Miniaturbild (z. B. 300 x 300) von einem Bild mit eingebettetem Miniaturbild anfordern, kann dies zu einem spürbaren Qualitätsverlust des Miniaturbilds führen .

Es ist möglicherweise besser, das Hauptbild durch Aufrufen der DrawImageMethode zu skalieren (anstatt das eingebettete Miniaturbild zu skalieren) .

Russell Troywest
quelle
5
Es kann im Allgemeinen nur für JPG-Bilder verwendet werden. Wenn Sie versuchen, die Größe eines PNG-Bilds wie folgt zu ändern, wird dieser Fehler angezeigt.
HBlackorby
Wirklich verwendet, um Miniaturbild 400x225 eines Full-HD-Fotos zu erhalten, und die Größe des resultierenden "Miniaturbilds" betrug 200 kB (Original 350 kB). Diese Methode sollte vermieden werden.
Vojtěch Dohnal
1
@ NathananaelJones, meinst du das ernst? ImageResizer ist für Unternehmen nicht kostenlos.
Ciaran Gallagher
26

Der folgende Code schreibt ein Bild proportional zur Antwort. Sie können den Code für Ihren Zweck ändern:

public void WriteImage(string path, int width, int height)
{
    Bitmap srcBmp = new Bitmap(path);
    float ratio = srcBmp.Width / srcBmp.Height;
    SizeF newSize = new SizeF(width, height * ratio);
    Bitmap target = new Bitmap((int) newSize.Width,(int) newSize.Height);
    HttpContext.Response.Clear();
    HttpContext.Response.ContentType = "image/jpeg";
    using (Graphics graphics = Graphics.FromImage(target))
    {
        graphics.CompositingQuality = CompositingQuality.HighSpeed;
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.CompositingMode = CompositingMode.SourceCopy;
        graphics.DrawImage(srcBmp, 0, 0, newSize.Width, newSize.Height);
        using (MemoryStream memoryStream = new MemoryStream()) 
        {
            target.Save(memoryStream, ImageFormat.Jpeg);
            memoryStream.WriteTo(HttpContext.Response.OutputStream);
        }
    }
    Response.End();
}
Priyan R.
quelle
Ich habe meinen lokalen Dateipfad im Zeichenfolgenpfad angegeben. Es wird zurückgegeben, dass das angegebene Pfadformat nicht unterstützt wird.
Gopal Palraj
Ich gab so ... var path = @ "C: \ Users \ Gopal \ Desktop \ files.jpeg"; Bitmap srcBmp = neue Bitmap (Pfad);
Gopal Palraj
Für diejenigen, die HttpResponseMessage verwenden:response.Content = new ByteArrayContent(memoryStream.ToArray());
Hp93
Vorsicht, dieser Code setzt voraus, dass die Bilder "horizontal" (Querformat) sind
Alex
8

Hier finden Sie ein vollständiges Beispiel für die Erstellung eines kleineren Bildes (Miniaturansicht). Dieses Snippet ändert die Größe des Bilds, dreht es bei Bedarf (wenn ein Telefon vertikal gehalten wurde) und füllt das Bild auf, wenn Sie quadratische Daumen erstellen möchten. Dieses Snippet erstellt ein JPEG, kann jedoch problemlos für andere Dateitypen geändert werden. Selbst wenn das Bild kleiner als die maximal zulässige Größe wäre, wird das Bild dennoch komprimiert und die Auflösung geändert, um Bilder mit derselben Auflösung und Komprimierungsstufe zu erstellen.

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

//set the resolution, 72 is usually good enough for displaying images on monitors
float imageResolution = 72;

//set the compression level. higher compression = better quality = bigger images
long compressionLevel = 80L;


public Image resizeImage(Image image, int maxWidth, int maxHeight, bool padImage)
{
    int newWidth;
    int newHeight;

    //first we check if the image needs rotating (eg phone held vertical when taking a picture for example)
    foreach (var prop in image.PropertyItems)
    {
        if (prop.Id == 0x0112)
        {
            int orientationValue = image.GetPropertyItem(prop.Id).Value[0];
            RotateFlipType rotateFlipType = getRotateFlipType(orientationValue);
            image.RotateFlip(rotateFlipType);
            break;
        }
    }

    //apply the padding to make a square image
    if (padImage == true)
    {
        image = applyPaddingToImage(image, Color.Red);
    }

    //check if the with or height of the image exceeds the maximum specified, if so calculate the new dimensions
    if (image.Width > maxWidth || image.Height > maxHeight)
    {
        double ratioX = (double)maxWidth / image.Width;
        double ratioY = (double)maxHeight / image.Height;
        double ratio = Math.Min(ratioX, ratioY);

        newWidth = (int)(image.Width * ratio);
        newHeight = (int)(image.Height * ratio);
    }
    else
    {
        newWidth = image.Width;
        newHeight = image.Height;
    }

    //start the resize with a new image
    Bitmap newImage = new Bitmap(newWidth, newHeight);

    //set the new resolution
    newImage.SetResolution(imageResolution, imageResolution);

    //start the resizing
    using (var graphics = Graphics.FromImage(newImage))
    {
        //set some encoding specs
        graphics.CompositingMode = CompositingMode.SourceCopy;
        graphics.CompositingQuality = CompositingQuality.HighQuality;
        graphics.SmoothingMode = SmoothingMode.HighQuality;
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

        graphics.DrawImage(image, 0, 0, newWidth, newHeight);
    }

    //save the image to a memorystream to apply the compression level
    using (MemoryStream ms = new MemoryStream())
    {
        EncoderParameters encoderParameters = new EncoderParameters(1);
        encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, compressionLevel);

        newImage.Save(ms, getEncoderInfo("image/jpeg"), encoderParameters);

        //save the image as byte array here if you want the return type to be a Byte Array instead of Image
        //byte[] imageAsByteArray = ms.ToArray();
    }

    //return the image
    return newImage;
}


//=== image padding
public Image applyPaddingToImage(Image image, Color backColor)
{
    //get the maximum size of the image dimensions
    int maxSize = Math.Max(image.Height, image.Width);
    Size squareSize = new Size(maxSize, maxSize);

    //create a new square image
    Bitmap squareImage = new Bitmap(squareSize.Width, squareSize.Height);

    using (Graphics graphics = Graphics.FromImage(squareImage))
    {
        //fill the new square with a color
        graphics.FillRectangle(new SolidBrush(backColor), 0, 0, squareSize.Width, squareSize.Height);

        //put the original image on top of the new square
        graphics.DrawImage(image, (squareSize.Width / 2) - (image.Width / 2), (squareSize.Height / 2) - (image.Height / 2), image.Width, image.Height);
    }

    //return the image
    return squareImage;
}


//=== get encoder info
private ImageCodecInfo getEncoderInfo(string mimeType)
{
    ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();

    for (int j = 0; j < encoders.Length; ++j)
    {
        if (encoders[j].MimeType.ToLower() == mimeType.ToLower())
        {
            return encoders[j];
        }
    }

    return null;
}


//=== determine image rotation
private RotateFlipType getRotateFlipType(int rotateValue)
{
    RotateFlipType flipType = RotateFlipType.RotateNoneFlipNone;

    switch (rotateValue)
    {
        case 1:
            flipType = RotateFlipType.RotateNoneFlipNone;
            break;
        case 2:
            flipType = RotateFlipType.RotateNoneFlipX;
            break;
        case 3:
            flipType = RotateFlipType.Rotate180FlipNone;
            break;
        case 4:
            flipType = RotateFlipType.Rotate180FlipX;
            break;
        case 5:
            flipType = RotateFlipType.Rotate90FlipX;
            break;
        case 6:
            flipType = RotateFlipType.Rotate90FlipNone;
            break;
        case 7:
            flipType = RotateFlipType.Rotate270FlipX;
            break;
        case 8:
            flipType = RotateFlipType.Rotate270FlipNone;
            break;
        default:
            flipType = RotateFlipType.RotateNoneFlipNone;
            break;
    }

    return flipType;
}


//== convert image to base64
public string convertImageToBase64(Image image)
{
    using (MemoryStream ms = new MemoryStream())
    {
        //convert the image to byte array
        image.Save(ms, ImageFormat.Jpeg);
        byte[] bin = ms.ToArray();

        //convert byte array to base64 string
        return Convert.ToBase64String(bin);
    }
}

Für die asp.net-Benutzer ein kleines Beispiel zum Hochladen einer Datei, Ändern der Größe und Anzeigen des Ergebnisses auf der Seite.

//== the button click method
protected void Button1_Click(object sender, EventArgs e)
{
    //check if there is an actual file being uploaded
    if (FileUpload1.HasFile == false)
    {
        return;
    }

    using (Bitmap bitmap = new Bitmap(FileUpload1.PostedFile.InputStream))
    {
        try
        {
            //start the resize
            Image image = resizeImage(bitmap, 256, 256, true);

            //to visualize the result, display as base64 image
            Label1.Text = "<img src=\"data:image/jpg;base64," + convertImageToBase64(image) + "\">";

            //save your image to file sytem, database etc here
        }
        catch (Exception ex)
        {
            Label1.Text = "Oops! There was an error when resizing the Image.<br>Error: " + ex.Message;
        }
    }
}
VDWWD
quelle
Ich mochte dieses Codebeispiel und entschied mich, es zu verwenden. Unabhängig davon, welche Änderungen ich an den verschiedenen Optionen vorgenommen habe (imageResolution, compressLevel, CompositingMode, CompositingQuality, SmoothingMode, InterpolationMode, PixelOffsetMode), hat sich die Größe der Bilddatei nur geringfügig verringert. Und ich habe nie einen Unterschied in dem erstellten Bild gesehen. Schließlich entschied ich mich, das Bild in einer Datei anstelle des Speicherstroms zu speichern und konnte drastische Änderungen feststellen. Für jeden, der dies verwendet, scheint das Speichern in einem Speicherstrom das zurückgegebene Bild nicht zu beeinflussen.
BLaminack
1

Hier ist ein Beispiel für die Konvertierung von hochauflösenden Bildern in Miniaturbilder.

protected void Button1_Click(object sender, EventArgs e)
{
    //----------        Getting the Image File
    System.Drawing.Image img = System.Drawing.Image.FromFile(Server.MapPath("~/profile/Avatar.jpg"));

    //----------        Getting Size of Original Image
    double imgHeight = img.Size.Height;
    double imgWidth = img.Size.Width;

    //----------        Getting Decreased Size
    double x = imgWidth / 200;
    int newWidth = Convert.ToInt32(imgWidth / x);
    int newHeight = Convert.ToInt32(imgHeight / x);

    //----------        Creating Small Image
    System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
    System.Drawing.Image myThumbnail = img.GetThumbnailImage(newWidth, newHeight, myCallback, IntPtr.Zero);

    //----------        Saving Image
    myThumbnail.Save(Server.MapPath("~/profile/NewImage.jpg"));
}
public bool ThumbnailCallback()
{
    return false;
}

Source- http://iknowledgeboy.blogspot.in/2014/03/c-creating-thumbnail-of-large-image-by.html

Kamalpreet
quelle