Ecco un modo molto più semplice:
Bitmap bmp = new Bitmap(1, 1);
Bitmap orig = (Bitmap)Bitmap.FromFile("path");
using (Graphics g = Graphics.FromImage(bmp))
{
// updated: the Interpolation mode needs to be set to
// HighQualityBilinear or HighQualityBicubic or this method
// doesn't work at all. With either setting, the results are
// slightly different from the averaging method.
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(orig, new Rectangle(0, 0, 1, 1));
}
Color pixel = bmp.GetPixel(0, 0);
// pixel will contain average values for entire orig Bitmap
byte avgR = pixel.R; // etc.
In sostanza, si utilizza DrawImage per copiare il bitmap originale in un bitmap 1-pixel. I valori RGB di quel 1 pixel rappresenteranno quindi le medie per l'intero originale. GetPixel è relativamente lento, ma solo quando lo si utilizza su una grande Bitmap, pixel per pixel. Chiamarlo una volta qui non è un problema.
L'utilizzo di LockBits è davvero veloce, ma alcuni utenti di Windows dispongono di criteri di sicurezza che impediscono l'esecuzione di codice "non sicuro". Lo dico perché questo fatto mi ha un po 'preso di recente.
Aggiornamento: con InterpolationMode impostato su HighQualityBicubic, questo metodo richiede circa il doppio del calcolo della media con LockBits; con HighQualityBilinear, richiede solo un po 'più lungo di LockBits. Quindi, a meno che i tuoi utenti non dispongano di una politica di sicurezza che vieta il codice unsafe
, sicuramente non usare il mio metodo.
Aggiornamento 2: con il passare del tempo, ora capisco perché questo approccio non funziona affatto. Anche gli algoritmi di interpolazione di alta qualità incorporano solo pochi pixel vicini, quindi c'è un limite a quanto un'immagine può essere schiacciata senza perdere informazioni. E schiacciare un'immagine fino a un pixel è ben oltre questo limite, indipendentemente dall'algoritmo che si utilizza.
L'unico modo per farlo sarebbe quello di restringere l'immagine in passaggi (magari ridurla di metà ogni volta) fino a ridurla alla dimensione di un pixel. Non riesco a esprimere a parole ciò che sarebbe una totale perdita di tempo scrivere qualcosa del genere, quindi sono contento di essermi fermato quando ci ho pensato. :)
Per favore, nessuno vota più per questa risposta - potrebbe essere la mia più stupida idea di sempre.
Bene, il metodo ingenuo sarebbe quello di andare pixel per pixel e ottenere i valori RGB, che sono sicuro non è quello che stai chiedendo. Puoi elaborare il tipo di media che stai cercando? –
Hai ragione. Spero sia meglio ora. – Mats
L'andare pixel per pixel può essere fatto in modo diverso - vedi le risposte. Mi chiedo se la GPU potrebbe aiutare. –