Prawidłowa odpowiedź może być poskładane z kilku innych odpowiedzi, ale żaden z nich nie jest kompletny, a niektóre przedstawiają bardzo złe pomysły (jak dwukrotne rysowanie obrazu).
Są trzy powody, dla artefaktów widzisz:
- Domyślna
Graphics.PixelOffsetMode
ustawienie powoduje, że wartości pikseli być próbą nieprawidłowo, powodując lekkie zniekształcenie obrazu, zwłaszcza na brzegach.
InterpolationMode.HighQualityBicubic
próbki pikseli spoza krawędzi obrazu, które domyślnie są przezroczyste. Te przezroczyste piksele są mieszane z pikselami krawędzi przez sampler, co powoduje półprzezroczyste krawędzie.
- Po zapisaniu obrazu półprzezroczystego w formacie, który nie obsługuje przezroczystości (na przykład JPEG), przezroczyste wartości są zastępowane przez czerń.
Wszystko to składa się na pół-czarne (tzn. Szare) krawędzie.
Prawidłowym sposobem usunięcia tych artefaktów jest użycie PixelOffsetMode.Half
i użycie obiektu ImageAttributes
do określenia grubości krawędzi, aby próbnik HighQualityBicubic
miał coś innego niż przezroczyste piksele do wypróbowania.
Istnieje kilka innych problemów związanych z kodem Ci wysłane także:
Bitmap
konstruktor został użyty jest inicjowanie nowych Bitmap
od rozmiaru oryginalnego obrazu, tak robisz operację zmiany rozmiaru dwukrotnie. Powinieneś użyć przeciążenia konstruktora o pożądanych wymiarach, aby utworzyć puste płótno.
Pamiętaj, że klasa Bitmap
reprezentuje niezarządzaną kopię obrazu w pamięci. Musi zostać usunięty, aby GDI + mógł zostać poinformowany o zwolnieniu tej pamięci, gdy skończysz. Zakładam, że robisz to w kodzie, który otrzymuje zwrot Image
, ale wskazuję to na wypadek, gdyby ktoś inny zapożyczył ten kod.
Ustawienie CompositingQuality.HighQuality
użyte w kodzie nie będzie miało żadnego efektu wizualnego, jeśli uzyskasz inne ustawienia w prawidłowy sposób i faktycznie będzie to miało negatywny wpływ na wydajność w połączeniu z domyślną wartością CompositingMode.SourceOver
. Możesz pominąć ustawienie CompositingQuality
i ustawić CompositingMode.SourceCopy
, aby uzyskać takie same wyniki i lepszą wydajność.
Ustawienie użyte w kodzie SmoothingMode
nie ma żadnego wpływu na DrawImage()
, więc można je usunąć.
Możesz przeczytać więcej informacji na temat ustawień Graphics
klasowych i ich wpływu na jakość obrazu i wydajność tutaj: http://photosauce.net/blog/post/image-scaling-with-gdi-part-3-drawimage-and-the-settings-that-affect-it
Zmieniony kod powinien wyglądać następująco:
public static Image Scale(Image sourceImage, int destWidth, int destHeight)
{
var toReturn = new Bitmap(destWidth, destHeight);
using (var graphics = Graphics.FromImage(toReturn))
using (var attributes = new ImageAttributes())
{
toReturn.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
attributes.SetWrapMode(WrapMode.TileFlipXY);
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.Half;
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.DrawImage(sourceImage, Rectangle.FromLTRB(0, 0, destWidth, destHeight), 0, 0, sourceImage.Width, sourceImage.Height, GraphicsUnit.Pixel, attributes);
}
return toReturn;
}
Co HTML wyglądać to wysyłane do przeglądarki w poszukiwaniu tych obrazów? – DOK
Jaki jest oryginalny typ obrazu? –
opublikować obraz wejściowy –