Domanda

Ho appena ricevuto una vera sorpresa quando ho caricato un file jpg e mi voltai e salvato con una qualità di 100 e la dimensione era quasi 4 volte l'originale. Per ulteriori indagini ho aperto e salvati senza impostare esplicitamente la qualità e la dimensione del file era esattamente lo stesso. Ho pensato che questo era perché nulla è cambiato quindi è appena iscritto esattamente lo stesso bit di nuovo ad un file. Per verificare questa ipotesi ho tracciato una linea di grande grasso diagonalmente attraverso l'immagine e salvato di nuovo senza impostare la qualità (questa volta ho atteso il file per saltare perché sarebbe "sporco"), ma è diminuito ~ 10Kb!

A questo punto io davvero non capisco cosa sta succedendo quando ho semplicemente chiamare Image.Save () w / out specifica una qualità di compressione. Come le dimensioni dei file così vicino (dopo che l'immagine viene modificata) alla dimensione originale quando nessuna qualità è ancora impostata quando ho impostato la qualità a 100 (in pratica nessuna compressione) la dimensione del file è molte volte più grande dell'originale?

Ho letto la documentazione relativa Image.Save () ed è privo di ogni dettaglio su ciò che accade dietro le quinte. Googled ogni modo mi viene in mente, ma non riesco a trovare tutte le ulteriori informazioni che spiegherebbe quello che sto vedendo. Ho lavorato per 31 ore di fila così forse mi manca qualcosa ovvio; 0)

Tutto questo è avvenuto mentre a implementare alcuni metodi di libreria per salvare le immagini in un database. Ho sovraccaricato il nostro metodo "SaveImage" per consentire l'impostazione di una qualità in modo esplicito e durante il mio test mi sono imbattuto nel dispari (per me) risultati spiegato sopra. Qualsiasi luce si può gettare sarà apprezzato.

Ecco un codice che illustrerà quello che sto vivendo:

string filename = @"C:\temp\image testing\hh.jpg";
string destPath = @"C:\temp\image testing\";

using(Image image = Image.FromFile(filename))
{
    ImageCodecInfo codecInfo = ImageUtils.GetEncoderInfo(ImageFormat.Jpeg);

    //  Set the quality
    EncoderParameters parameters = new EncoderParameters(1);

    // Quality: 10
    parameters.Param[0] = new EncoderParameter(
        System.Drawing.Imaging.Encoder.Quality, 10L);
    image.Save(destPath + "10.jpg", codecInfo, parameters);

    // Quality: 75
    parameters.Param[0] = new EncoderParameter(
        System.Drawing.Imaging.Encoder.Quality, 75L);
    image.Save(destPath + "75.jpg", codecInfo, parameters);

    // Quality: 100
    parameters.Param[0] = new EncoderParameter(
        System.Drawing.Imaging.Encoder.Quality, 100L);
    image.Save(destPath + "100.jpg", codecInfo, parameters);

    //  default
    image.Save(destPath + "default.jpg", ImageFormat.Jpeg);

    //  Big line across image
    using (Graphics g = Graphics.FromImage(image))
    {
        using(Pen pen = new Pen(Color.Red, 50F))
        {
            g.DrawLine(pen, 0, 0, image.Width, image.Height);
        }
    }

    image.Save(destPath + "big red line.jpg", ImageFormat.Jpeg);
}

public static ImageCodecInfo GetEncoderInfo(ImageFormat format)
{
    return ImageCodecInfo.GetImageEncoders().ToList().Find(delegate(ImageCodecInfo codec)
    {
        return codec.FormatID == format.Guid;
    });
}
È stato utile?

Soluzione

Utilizzando riflettore, si scopre Image.Save() riduce alla funzione GDI + GdipSaveImageToFile , con il NULL encoderParams. Quindi penso che la domanda è che cosa il codificatore JPEG fa quando si ottiene un encoderParams nullo. Il 75% è stato suggerito qui, ma non riesco a trovare alcun riferimento solido.

Modifica Si potrebbe forse scoprire per lei eseguendo il programma di cui sopra per i valori di qualità di 1..100 e confrontandoli con il jpg salvato con la qualità di default (utilizzando, per esempio, FC.exe / B)

Altri suggerimenti

IIRC, è il 75%, ma io non ricordo dove ho letto questo.

Non so molto circa il metodo di Image.Save, ma si può dire che l'aggiunta di quella linea di grasso avrebbe logicly ridurre le dimensioni delle immagini jpg. Ciò è dovuto al modo in cui un jpg viene salvato (e codificati).

La linea nera spessa rende per una codifica molto semplice e più piccola (Se ricordo correttamente questa è relevent soprattutto dopo la trasformata coseno discreta), quindi l'immagine modificata può essere memorizzato usando meno dati (byte).

jpg codifica passi

Per quanto riguarda i cambiamenti nelle dimensioni (senza la linea aggiunta), non sono sicuro di quale immagine si riaperto e risalvato

  

Per indagare ulteriormente ho aperto e salvati senza impostare esplicitamente la qualità e la dimensione del file era esattamente lo stesso

Se avete aperto l'immagine del vecchio (originale dimensioni normali) e salvato di nuovo, quindi forse la compressione di default e la compressione dell'immagine originale sono gli stessi. Se avete aperto la nuova immagine (4X più grande) e salvato di nuovo, quindi forse la compressione di default per il salvataggio metodo deriva dall'immagine (come lo era quando caricato).

Ancora una volta, non so il metodo di salvataggio, quindi sto solo gettando le idee (magari vi daranno un vantaggio).

Quando si salva un'immagine come file JPEG con un livello di qualità di <100%, si stanno introducendo artefatti nel salvato-off delle immagini, che sono un effetto collaterale del processo di compressione. Questo è il motivo per ri-salvare l'immagine al 100% è in aumento la dimensione del file al di là della originale -. Ironicamente c'è più informazioni presenti nel bitmap

Questo è anche il motivo per cui si dovrebbe sempre cercare di salvare in un formato non-lossy (come PNG) se avete intenzione di fare le modifiche al file in seguito, altrimenti sarete che influenzano la qualità della produzione attraverso la perdita di dati multiple trasformazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top