Exemplo n.º 1
0
        public static void ToReplacedColor(BitmapHolder bmp, int r, int g, int b, int a)
        {
            var nWidth  = bmp.Width;
            var nHeight = bmp.Height;
            var len     = bmp.PixelCount;

            for (var i = 0; i < len; i++)
            {
                var c            = bmp.GetPixelAsInt(i);
                var currentAlpha = (c >> 24) & 0x000000FF;
                var aNew         = (int)(currentAlpha * (a / currentAlpha));

                var rNew = r;
                var gNew = g;
                var bNew = b;

                if (rNew > 255)
                {
                    rNew = 255;
                }

                if (gNew > 255)
                {
                    gNew = 255;
                }

                if (bNew > 255)
                {
                    bNew = 255;
                }

                bmp.SetPixel(i, (aNew << 24) | (rNew << 16) | (gNew << 8) | bNew);
            }
        }
Exemplo n.º 2
0
        public static BitmapHolder ToFlipped(BitmapHolder bmp, FlipType flipMode)
        {
            // Use refs for faster access (really important!) speeds up a lot!
            var          w      = bmp.Width;
            var          h      = bmp.Height;
            var          i      = 0;
            BitmapHolder result = new BitmapHolder(new byte[bmp.PixelData.Length], w, h);

            if (flipMode == FlipType.Vertical)
            {
                var rp = result.PixelData;
                for (var y = h - 1; y >= 0; y--)
                {
                    for (var x = 0; x < w; x++)
                    {
                        var srcInd = y * w + x;
                        result.SetPixel(i, bmp.GetPixelAsInt(srcInd));
                        i++;
                    }
                }
            }
            else
            {
                var rp = result.PixelData;
                for (var y = 0; y < h; y++)
                {
                    for (var x = w - 1; x >= 0; x--)
                    {
                        var srcInd = y * w + x;
                        result.SetPixel(i, bmp.GetPixelAsInt(srcInd));
                        i++;
                    }
                }
            }

            return(result);
        }
        public static void ToGrayscale(BitmapHolder bmp)
        {
            var nWidth = bmp.Width;
            var nHeight = bmp.Height;

            var len = bmp.PixelCount;

            for (var i = 0; i < len; i++)
            {
                var c = bmp.GetPixelAsInt(i);
                var a = (c >> 24) & 0x000000FF;
                var r = (c >> 16) & 0x000000FF;
                var g = (c >> 8) & 0x000000FF;
                var b = (c) & 0x000000FF;

                // Convert to gray with constant factors 0.2126, 0.7152, 0.0722
                var gray = (r * 6966 + g * 23436 + b * 2366) >> 15;
                r = g = b = gray;

                bmp.SetPixel(i, (a << 24) | (r << 16) | (g << 8) | b);
            }
        }
Exemplo n.º 4
0
        public static void ToSepia(BitmapHolder bmp)
        {
            var nWidth  = bmp.Width;
            var nHeight = bmp.Height;
            var len     = bmp.PixelCount;

            for (var i = 0; i < len; i++)
            {
                var c = bmp.GetPixelAsInt(i);
                var a = (c >> 24) & 0x000000FF;
                var r = (c >> 16) & 0x000000FF;
                var g = (c >> 8) & 0x000000FF;
                var b = (c) & 0x000000FF;

                var rNew = (int)Math.Min((.393 * r) + (.769 * g) + (.189 * (b)), 255.0);
                var gNew = (int)Math.Min((.349 * r) + (.686 * g) + (.168 * (b)), 255.0);
                var bNew = (int)Math.Min((.272 * r) + (.534 * g) + (.131 * (b)), 255.0);

                if (rNew > 255)
                {
                    rNew = 255;
                }

                if (gNew > 255)
                {
                    gNew = 255;
                }

                if (bNew > 255)
                {
                    bNew = 255;
                }

                bmp.SetPixel(i, (a << 24) | (rNew << 16) | (gNew << 8) | bNew);
            }
        }
        public static void ToColorSpace(BitmapHolder bmp, float[][] rgbawMatrix)
        {
            var r0 = rgbawMatrix[0][0];
            var r1 = rgbawMatrix[0][1];
            var r2 = rgbawMatrix[0][2];
            var r3 = rgbawMatrix[0][3];

            var g0 = rgbawMatrix[1][0];
            var g1 = rgbawMatrix[1][1];
            var g2 = rgbawMatrix[1][2];
            var g3 = rgbawMatrix[1][3];

            var b0 = rgbawMatrix[2][0];
            var b1 = rgbawMatrix[2][1];
            var b2 = rgbawMatrix[2][2];
            var b3 = rgbawMatrix[2][3];

            var a0 = rgbawMatrix[3][0];
            var a1 = rgbawMatrix[3][1];
            var a2 = rgbawMatrix[3][2];
            var a3 = rgbawMatrix[3][3];

            var rOffset = rgbawMatrix[4][0];
            var gOffset = rgbawMatrix[4][1];
            var bOffset = rgbawMatrix[4][2];
            var aOffset = rgbawMatrix[4][3];

            var nWidth  = bmp.Width;
            var nHeight = bmp.Height;
            var len     = bmp.PixelCount;

            for (var i = 0; i < len; i++)
            {
                var c = bmp.GetPixelAsInt(i);
                var a = (c >> 24) & 0x000000FF;
                var r = (c >> 16) & 0x000000FF;
                var g = (c >> 8) & 0x000000FF;
                var b = (c) & 0x000000FF;

                var rNew = (int)(r * r0 + g * g0 + b * b0 + a * a0 + rOffset);
                var gNew = (int)(r * r1 + g * g1 + b * b1 + a * a1 + gOffset);
                var bNew = (int)(r * r2 + g * g2 + b * b2 + a * a2 + bOffset);
                var aNew = (int)(r * r3 + g * g3 + b * b3 + a * a3 + aOffset);

                if (rNew > 255)
                {
                    rNew = 255;
                }

                if (gNew > 255)
                {
                    gNew = 255;
                }

                if (bNew > 255)
                {
                    bNew = 255;
                }

                if (aNew > 255)
                {
                    aNew = 255;
                }

                if (rNew < 0)
                {
                    rNew = 0;
                }

                if (gNew < 0)
                {
                    gNew = 0;
                }

                if (bNew < 0)
                {
                    bNew = 0;
                }

                if (aNew < 0)
                {
                    aNew = 0;
                }

                bmp.SetPixel(i, (aNew << 24) | (rNew << 16) | (gNew << 8) | bNew);
            }
        }
        // Source: http://incubator.quasimondo.com/processing/superfast_blur.php
        public static void ToLegacyBlurred(BitmapHolder source, int radius)
        {
            int w   = source.Width;
            int h   = source.Height;
            int wm  = w - 1;
            int hm  = h - 1;
            int wh  = w * h;
            int div = radius + radius + 1;

            int[] r = new int[wh];
            int[] g = new int[wh];
            int[] b = new int[wh];
            int   rsum, gsum, bsum, x, y, i, p, p1, p2, yp, yi, yw;

            int[] vmin = new int[Math.Max(w, h)];
            int[] vmax = new int[Math.Max(w, h)];

            int[] dv = new int[256 * div];
            for (i = 0; i < 256 * div; i++)
            {
                dv[i] = (i / div);
            }

            yw = yi = 0;

            for (y = 0; y < h; y++)
            {
                rsum = gsum = bsum = 0;
                for (i = -radius; i <= radius; i++)
                {
                    p     = source.GetPixelAsInt(yi + Math.Min(wm, Math.Max(i, 0)));
                    rsum += (p & 0xff0000) >> 16;
                    gsum += (p & 0x00ff00) >> 8;
                    bsum += p & 0x0000ff;
                }
                for (x = 0; x < w; x++)
                {
                    r[yi] = dv[rsum];
                    g[yi] = dv[gsum];
                    b[yi] = dv[bsum];

                    if (y == 0)
                    {
                        vmin[x] = Math.Min(x + radius + 1, wm);
                        vmax[x] = Math.Max(x - radius, 0);
                    }
                    p1 = source.GetPixelAsInt(yw + vmin[x]);
                    p2 = source.GetPixelAsInt(yw + vmax[x]);

                    rsum += ((p1 & 0xff0000) - (p2 & 0xff0000)) >> 16;
                    gsum += ((p1 & 0x00ff00) - (p2 & 0x00ff00)) >> 8;
                    bsum += (p1 & 0x0000ff) - (p2 & 0x0000ff);
                    yi++;
                }
                yw += w;
            }

            for (x = 0; x < w; x++)
            {
                rsum = gsum = bsum = 0;
                yp   = -radius * w;
                for (i = -radius; i <= radius; i++)
                {
                    yi    = Math.Max(0, yp) + x;
                    rsum += r[yi];
                    gsum += g[yi];
                    bsum += b[yi];
                    yp   += w;
                }
                yi = x;
                for (y = 0; y < h; y++)
                {
                    // Preserve alpha channel: ( 0xff000000 & pix[yi] )
                    source.SetPixel(yi, (int)((0xff000000 & (uint)source.GetPixelAsInt(yi)) | (uint)(dv[rsum] << 16) | (uint)(dv[gsum] << 8) | (uint)dv[bsum]));
                    if (x == 0)
                    {
                        vmin[y] = Math.Min(y + radius + 1, hm) * w;
                        vmax[y] = Math.Max(y - radius, 0) * w;
                    }
                    p1 = x + vmin[y];
                    p2 = x + vmax[y];

                    rsum += r[p1] - r[p2];
                    gsum += g[p1] - g[p2];
                    bsum += b[p1] - b[p2];

                    yi += w;
                }
            }
        }
        public static BitmapHolder ToRotated(BitmapHolder source, double degrees, bool ccw, bool resize)
        {
            if (degrees == 0 || degrees % 360 == 0)
            {
                return(source);
            }

            if (ccw)
            {
                degrees = 360d - degrees;
            }

            // rotating clockwise, so it's negative relative to Cartesian quadrants
            double cnAngle = -1.0 * (Math.PI / 180) * degrees;

            // general iterators
            int i, j;
            // calculated indices in Cartesian coordinates
            int    x, y;
            double fDistance, fPolarAngle;
            // for use in neighboring indices in Cartesian coordinates
            int iFloorX, iCeilingX, iFloorY, iCeilingY;
            // calculated indices in Cartesian coordinates with trailing decimals
            double fTrueX, fTrueY;
            // for interpolation
            double fDeltaX, fDeltaY;

            // interpolated "top" pixels
            double fTopRed, fTopGreen, fTopBlue, fTopAlpha;

            // interpolated "bottom" pixels
            double fBottomRed, fBottomGreen, fBottomBlue, fBottomAlpha;

            // final interpolated color components
            int iRed, iGreen, iBlue, iAlpha;

            int iCentreX, iCentreY;
            int iDestCentreX, iDestCentreY;
            int iWidth, iHeight, newWidth, newHeight;

            iWidth  = source.Width;
            iHeight = source.Height;

            if (!resize || (degrees % 180 == 0))
            {
                newWidth  = iWidth;
                newHeight = iHeight;
            }
            else
            {
                var rad = degrees / (180 / Math.PI);
                newWidth  = (int)Math.Ceiling(Math.Abs(Math.Sin(rad) * iHeight) + Math.Abs(Math.Cos(rad) * iWidth));
                newHeight = (int)Math.Ceiling(Math.Abs(Math.Sin(rad) * iWidth) + Math.Abs(Math.Cos(rad) * iHeight));
            }


            iCentreX = iWidth / 2;
            iCentreY = iHeight / 2;

            iDestCentreX = newWidth / 2;
            iDestCentreY = newHeight / 2;

            var newSource = new BitmapHolder(new byte[newWidth * newHeight * 4], newWidth, newHeight);
            var oldw      = source.Width;

            // assigning pixels of destination image from source image
            // with bilinear interpolation
            for (i = 0; i < newHeight; ++i)
            {
                for (j = 0; j < newWidth; ++j)
                {
                    // convert raster to Cartesian
                    x = j - iDestCentreX;
                    y = iDestCentreY - i;

                    // convert Cartesian to polar
                    fDistance = Math.Sqrt(x * x + y * y);
                    if (x == 0)
                    {
                        if (y == 0)
                        {
                            // center of image, no rotation needed
                            newSource.SetPixel(i * newWidth + j, source.GetPixelAsInt(iCentreY * oldw + iCentreX));
                            continue;
                        }
                        if (y < 0)
                        {
                            fPolarAngle = 1.5 * Math.PI;
                        }
                        else
                        {
                            fPolarAngle = 0.5 * Math.PI;
                        }
                    }
                    else
                    {
                        fPolarAngle = Math.Atan2(y, x);
                    }

                    // the crucial rotation part
                    // "reverse" rotate, so minus instead of plus
                    fPolarAngle -= cnAngle;

                    // convert polar to Cartesian
                    fTrueX = fDistance * Math.Cos(fPolarAngle);
                    fTrueY = fDistance * Math.Sin(fPolarAngle);

                    // convert Cartesian to raster
                    fTrueX = fTrueX + iCentreX;
                    fTrueY = iCentreY - fTrueY;

                    iFloorX   = (int)(Math.Floor(fTrueX));
                    iFloorY   = (int)(Math.Floor(fTrueY));
                    iCeilingX = (int)(Math.Ceiling(fTrueX));
                    iCeilingY = (int)(Math.Ceiling(fTrueY));

                    // check bounds
                    if (iFloorX < 0 || iCeilingX < 0 || iFloorX >= iWidth || iCeilingX >= iWidth || iFloorY < 0 ||
                        iCeilingY < 0 || iFloorY >= iHeight || iCeilingY >= iHeight)
                    {
                        continue;
                    }

                    fDeltaX = fTrueX - iFloorX;
                    fDeltaY = fTrueY - iFloorY;

                    var clrTopLeft     = source.GetPixelAsInt(iFloorY * oldw + iFloorX);
                    var clrTopRight    = source.GetPixelAsInt(iFloorY * oldw + iCeilingX);
                    var clrBottomLeft  = source.GetPixelAsInt(iCeilingY * oldw + iFloorX);
                    var clrBottomRight = source.GetPixelAsInt(iCeilingY * oldw + iCeilingX);

                    fTopAlpha = (1 - fDeltaX) * ((clrTopLeft >> 24) & 0xFF) + fDeltaX * ((clrTopRight >> 24) & 0xFF);
                    fTopRed   = (1 - fDeltaX) * ((clrTopLeft >> 16) & 0xFF) + fDeltaX * ((clrTopRight >> 16) & 0xFF);
                    fTopGreen = (1 - fDeltaX) * ((clrTopLeft >> 8) & 0xFF) + fDeltaX * ((clrTopRight >> 8) & 0xFF);
                    fTopBlue  = (1 - fDeltaX) * (clrTopLeft & 0xFF) + fDeltaX * (clrTopRight & 0xFF);

                    // linearly interpolate horizontally between bottom neighbors
                    fBottomAlpha = (1 - fDeltaX) * ((clrBottomLeft >> 24) & 0xFF) + fDeltaX * ((clrBottomRight >> 24) & 0xFF);
                    fBottomRed   = (1 - fDeltaX) * ((clrBottomLeft >> 16) & 0xFF) + fDeltaX * ((clrBottomRight >> 16) & 0xFF);
                    fBottomGreen = (1 - fDeltaX) * ((clrBottomLeft >> 8) & 0xFF) + fDeltaX * ((clrBottomRight >> 8) & 0xFF);
                    fBottomBlue  = (1 - fDeltaX) * (clrBottomLeft & 0xFF) + fDeltaX * (clrBottomRight & 0xFF);

                    // linearly interpolate vertically between top and bottom interpolated results
                    iRed   = (int)(Math.Round((1 - fDeltaY) * fTopRed + fDeltaY * fBottomRed));
                    iGreen = (int)(Math.Round((1 - fDeltaY) * fTopGreen + fDeltaY * fBottomGreen));
                    iBlue  = (int)(Math.Round((1 - fDeltaY) * fTopBlue + fDeltaY * fBottomBlue));
                    iAlpha = (int)(Math.Round((1 - fDeltaY) * fTopAlpha + fDeltaY * fBottomAlpha));

                    // make sure color values are valid
                    if (iRed < 0)
                    {
                        iRed = 0;
                    }
                    if (iRed > 255)
                    {
                        iRed = 255;
                    }
                    if (iGreen < 0)
                    {
                        iGreen = 0;
                    }
                    if (iGreen > 255)
                    {
                        iGreen = 255;
                    }
                    if (iBlue < 0)
                    {
                        iBlue = 0;
                    }
                    if (iBlue > 255)
                    {
                        iBlue = 255;
                    }
                    if (iAlpha < 0)
                    {
                        iAlpha = 0;
                    }
                    if (iAlpha > 255)
                    {
                        iAlpha = 255;
                    }

                    var a = iAlpha + 1;

                    var val = (iAlpha << 24)
                              | ((byte)((iRed * a) >> 8) << 16)
                              | ((byte)((iGreen * a) >> 8) << 8)
                              | ((byte)((iBlue * a) >> 8));
                    newSource.SetPixel(i * newWidth + j, val);
                }
            }

            return(newSource);
        }