Desidero una funzione che riduca le dimensioni dell'immagine.Ridurre le dimensioni dell'immagine in C#
La funzione dovrebbe richiedere l'URL dell'immagine, controllare l'immagine 4MB o più grande e se è quindi ridimensionarla ad un amatore allora 4MB e restituire i byte.
devo metodo successivo:
public byte[] ResizeImage(string url)
{
var uri = new Uri(url);
var c = new WebClient();
var oldImgStream = new MemoryStream(c.DownloadData(uri));
if (oldImgStream.Length <= 4194304)
{
return oldImgStream.ToArray();
}
using (var oldImage = new Bitmap(oldImgStream))
using (var newImageStream = new MemoryStream())
{
var format = oldImage.RawFormat;
float resizePercent = (float)4194304/oldImgStream.Length;
var newImage = ResizeImageByPercent(oldImage, resizePercent);
newImage.Save(newImageStream, format);
return newImageStream.ToArray();
}
}
public static Bitmap ResizeImageByPercent(Bitmap image, float resizePercent)
{
//Set minimum resizePercentage to 80%
resizePercent = resizePercent > 0.8 ? (float)0.8 : resizePercent;
int newWidth = (int)(image.Width * resizePercent);
int newHeight = (int)(image.Height * resizePercent);
var newImage = new Bitmap(newWidth, newHeight);
using (var graphics = Graphics.FromImage(newImage))
{
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
graphics.FillRectangle(Brushes.Transparent, 0, 0, newWidth, newHeight);
graphics.DrawImage(image, 0, 0, newWidth, newHeight);
return newImage;
}
}
Ma questo non funziona bene.
Ho un'immagine jpg come esempio.
La dimensione dell'immagine è leggermente superiore a 4 MB (4194587 byte). Risoluzione dell'immagine è 2272 x 1704.
Così quando provo a ridimensionare questa immagine con il mio metodo sopra. E prima calcolare "resizePercentage" come:
float resizePercent = (float)4194304/oldImgStream.Length;
resizePercent = (float)4194304/4194587;
resizePercent = 0.9999325 //(99.99325%)
Anzi, perché vi ho posto minimo di resizePercent sarà impostato a 0.8 (80%).
resizePercent = 0.8;
Quindi calcola nuova larghezza e altezza con questo resizePercent.
E la nuova risoluzione sarà: 1817 x 1363 e l'immagine verrà ridimensionata a nuova risoluzione. Ma dopo essere stato salvato nello stream e letto byte, restituisce un'immagine ancora più grande. Il sito dell'immagine restituita è "5146056 byte" 5MB
Così chiunque ha idea di come implementarlo, o cosa non va in questo mio metodo in modo che restituisca un'immagine più grande, anche la risoluzione è ridotta.
dovrei essere in grado di ridurre le dimensioni delle immagini PNG, JPG e GIF
Non si conosce la qualità della compressione jpg applicata quando si riceve l'immagine. Quindi forse stai salvando l'immagine con una qualità più alta (cioè meno compressione) rispetto all'immagine originale. Il problema persiste quando lavori con immagini bmp? – wertzui
Se l'immagine di prova è un JPEG, probabilmente è stata compressa con un rapporto di compressione più alto di quanto .NET usi per impostazione predefinita. Poiché i JPEG utilizzano la compressione con perdita, è disponibile un'ampia gamma di rapporti di compressione; determineranno quanto appare sgranata l'immagine risultante. Per i PNG, che sono senza perdita di dati, è comunque possibile che l'immagine originale sia stata compressa da un algoritmo migliore di quello utilizzato da .NET. E così via. – adv12