public void DownScale32(int newWidth, int newHeight)
{
QBitmap newBitmap = new QBitmap(new Bitmap(newWidth, newHeight, bitmap.PixelFormat));
if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
throw new Exception("DownsScale32 only works on 32 bit images");
float xscale = (float)bitmapData.Width / newWidth;
float yscale = (float)bitmapData.Height / newHeight;
byte r = 0, g = 0, b = 0, a = 0;
float summedR = 0f;
float summedG = 0f;
float summedB = 0f;
float summedA = 0f;
int left, right, top, bottom; //the area of old pixels covered by the new bitmap
float targetStartX, targetEndX;
float targetStartY, targetEndY;
float leftF, rightF, topF, bottomF; //edges of new pixel in old pixel coords
float weight;
float weightScale = xscale * yscale;
float totalColourWeight = 0f;
for (int m = 0; m < newHeight; m++)
{
for (int n = 0; n < newWidth; n++)
{
leftF = n * xscale;
rightF = (n + 1) * xscale;
topF = m * yscale;
bottomF = (m + 1) * yscale;
left = (int)leftF;
right = (int)rightF;
top = (int)topF;
bottom = (int)bottomF;
if (left < 0) left = 0;
if (top < 0) top = 0;
if (right >= bitmapData.Width) right = bitmapData.Width - 1;
if (bottom >= bitmapData.Height) bottom = bitmapData.Height - 1;
summedR = 0f;
summedG = 0f;
summedB = 0f;
summedA = 0f;
totalColourWeight = 0f;
for (int j = top; j <= bottom; j++)
{
for (int i = left; i <= right; i++)
{
targetStartX = Math.Max(leftF, i);
targetEndX = Math.Min(rightF, i + 1);
targetStartY = Math.Max(topF, j);
targetEndY = Math.Min(bottomF, j + 1);
weight = (targetEndX - targetStartX) * (targetEndY - targetStartY);
GetPixel32(i, j, ref r, ref g, ref b, ref a);
summedA += weight * a;
if (a != 0)
{
summedR += weight * r;
summedG += weight * g;
summedB += weight * b;
totalColourWeight += weight;
}
}
}
summedR /= totalColourWeight;
summedG /= totalColourWeight;
summedB /= totalColourWeight;
summedA /= weightScale;
if (summedR < 0) summedR = 0f;
if (summedG < 0) summedG = 0f;
if (summedB < 0) summedB = 0f;
if (summedA < 0) summedA = 0f;
if (summedR >= 256) summedR = 255;
if (summedG >= 256) summedG = 255;
if (summedB >= 256) summedB = 255;
if (summedA >= 256) summedA = 255;
newBitmap.PutPixel32(n, m, (byte)summedR, (byte)summedG, (byte)summedB, (byte)summedA);
}
}
this.Free();
this.bitmap = newBitmap.bitmap;
this.bitmapData = newBitmap.bitmapData;
}