示例#1
0
        /// <summary>
        /// Transform this image to a greyscale version out-of-place
        /// </summary>
        /// <param name="source">The source image</param>
        /// <param name="output">The image to write to</param>
        /// <returns>The output writable lockbit image</returns>
        public static WritableLockBitImage Transform(WritableLockBitImage source, WritableLockBitImage output)
        {
            if (source.Locked || output.Locked)
            {
                throw new ArgumentException("Lockbit image is locked.");
            }

            for (int y = 0; y < source.Height; y++)
            {
                for (int x = 0; x < source.Width; x++)
                {
                    Color sourcePixel = source.GetPixel(x, y);

                    int greyColor =
                        (int)Math.Floor(sourcePixel.R * 0.299) +
                        (int)Math.Floor(sourcePixel.G * 0.587) +
                        (int)Math.Floor(sourcePixel.B * 0.114);

                    Color greyScale = Color.FromArgb(
                        greyColor,
                        greyColor,
                        greyColor
                        );
                    output.SetPixel(x, y, greyScale);
                }
            }

            return(output);
        }
 private static void CopyPixels(WritableLockBitImage sourceImage, WritableLockBitImage destImage)
 {
     for (int row = 0; row < sourceImage.Height; row++)
     {
         for (int col = 0; col < sourceImage.Width; col++)
         {
             destImage.SetPixel(col, row, sourceImage.GetPixel(col, row));
         }
     }
 }
示例#3
0
        private static int[] CoreCalculateSobelMatrix(WritableLockBitImage sourceImage, int[] firstKernel, int[] secondKernel)
        {
            // Go through each pixel in the source image
            int[] intermediateResult = new int[sourceImage.Height * sourceImage.Width];
            int[] inputBuffer        = new int[3];
            int   width = sourceImage.Width;

            for (int row = 0; row < sourceImage.Height; row++)
            {
                for (int col = 0; col < sourceImage.Width; col++)
                {
                    // Set the input buffer
                    inputBuffer[0] = col > 0 ? sourceImage.GetPixel(col - 1, row).R : 0;
                    inputBuffer[1] = sourceImage.GetPixel(col, row).R;
                    inputBuffer[2] = col < sourceImage.Width - 1 ? sourceImage.GetPixel(col + 1, row).R : 0;

                    // Convolute it with the vector
                    intermediateResult[row * width + col] = ConvoluteOneDimensionalVector(inputBuffer, firstKernel);
                }
            }

            // Go through each result in the intermediate result
            int[] finalMatrix = new int[sourceImage.Height * sourceImage.Width];
            for (int row = 0; row < sourceImage.Height; row++)
            {
                for (int col = 0; col < sourceImage.Width; col++)
                {
                    // Set input buffer
                    inputBuffer[0] = row > 0 ? intermediateResult[((row - 1) * width) + col] : 0;
                    inputBuffer[1] = intermediateResult[row * width + col];
                    inputBuffer[2] = row < sourceImage.Height - 1 ? intermediateResult[((row + 1) * width) + col] : 0;

                    // Convolute it with the second vector
                    finalMatrix[row * width + col] = ConvoluteOneDimensionalVector(inputBuffer, secondKernel);
                }
            }

            return(finalMatrix);
        }
示例#4
0
        private static byte[] CalculateGrayScaleThumbnail(WritableLockBitImage image)
        {
            byte[] buffer = new byte[image.Width * image.Height];
            for (int row = 0; row < image.Height; row++)
            {
                for (int col = 0; col < image.Width; col++)
                {
                    buffer[row * image.Width + col] = image.GetPixel(col, row).R;
                }
            }

            return(ByteCompressor.Compress(buffer));
        }
        /// <summary>
        /// Quantisize a photo by ceiling or flooring each value depending one whether it's above or below the median value
        /// </summary>
        /// <param name="sourceImage">The source image</param>
        /// <param name="outputImage">The image to write to</param>
        /// <param name="maxValue">The value to quantize the maximum value to</param>
        /// <returns>The output image, but returned for convenience</returns>
        public static WritableLockBitImage Transform(WritableLockBitImage sourceImage, WritableLockBitImage outputImage, byte maxValue = byte.MaxValue)
        {
            Color medianColor = GetMedianColorValue(sourceImage);

            for (int row = 0; row < sourceImage.Height; row++)
            {
                for (int col = 0; col < sourceImage.Width; col++)
                {
                    // Quantisize the individual channels
                    Color currentColor = sourceImage.GetPixel(col, row);
                    byte  outputRed, outputGreen, outputBlue;
                    if (currentColor.R < medianColor.R)
                    {
                        outputRed = 0;
                    }
                    else
                    {
                        outputRed = maxValue;
                    }

                    if (currentColor.G < medianColor.G)
                    {
                        outputGreen = 0;
                    }
                    else
                    {
                        outputGreen = maxValue;
                    }

                    if (currentColor.B < medianColor.B)
                    {
                        outputBlue = 0;
                    }
                    else
                    {
                        outputBlue = maxValue;
                    }

                    outputImage.SetPixel(col, row, Color.FromArgb(outputRed, outputGreen, outputBlue));
                }
            }

            return(outputImage);
        }
        private static Color GetMedianColorValue(WritableLockBitImage sourceImage)
        {
            var setOfRedColorValues   = new HashSet <int>();
            var setOfGreenColorValues = new HashSet <int>();
            var setOfBlueColorValues  = new HashSet <int>();

            for (int row = 0; row < sourceImage.Height; row++)
            {
                for (int col = 0; col < sourceImage.Width; col++)
                {
                    Color color = sourceImage.GetPixel(col, row);
                    setOfRedColorValues.Add(color.R);
                    setOfGreenColorValues.Add(color.G);
                    setOfBlueColorValues.Add(color.B);
                }
            }

            List <int> listOfRedColorValues   = setOfRedColorValues.ToList();
            List <int> listOfGreenColorValues = setOfRedColorValues.ToList();
            List <int> listOfBlueColorValues  = setOfRedColorValues.ToList();

            listOfRedColorValues.Sort();
            listOfGreenColorValues.Sort();
            listOfBlueColorValues.Sort();

            int count = listOfRedColorValues.Count;
            int medianRed, medianGreen, medianBlue;

            if (count % 2 == 0)
            {
                medianRed   = (int)Math.Round((listOfRedColorValues[count / 2] + listOfRedColorValues[count / 2 - 1]) / 2.0);
                medianGreen = (int)Math.Round((listOfGreenColorValues[count / 2] + listOfGreenColorValues[count / 2 - 1]) / 2.0);
                medianBlue  = (int)Math.Round((listOfBlueColorValues[count / 2] + listOfBlueColorValues[count / 2 - 1]) / 2.0);
            }
            else
            {
                medianRed   = listOfRedColorValues[count / 2];
                medianGreen = listOfGreenColorValues[count / 2];
                medianBlue  = listOfBlueColorValues[count / 2];
            }

            return(Color.FromArgb(medianRed, medianGreen, medianBlue));
        }
示例#7
0
        /// <summary>
        /// Calculate the DCT
        /// </summary>
        /// <param name="sourceImage">The source image to find the DCT of</param>
        /// <returns>The DCT coefficients</returns>
        public static double[,] Transform(WritableLockBitImage sourceImage)
        {
            if (sourceImage.Width != sourceImage.Height)
            {
                throw new ArgumentException("DCTs can only be calculated on square matrices");
            }

            byte[,] sourceMatrix = new byte[sourceImage.Height, sourceImage.Width];
            for (int y = 0; y < sourceImage.Height; y++)
            {
                for (int x = 0; x < sourceImage.Width; x++)
                {
                    // We only need the greyscale (luminance)
                    sourceMatrix[y, x] = sourceImage.GetPixel(x, y).R;
                }
            }

            return(Calculate(sourceMatrix));
        }
示例#8
0
        private static void PerformHorizontalBoxBlurAcc(WritableLockBitImage sourceImage, WritableLockBitImage outputImage, int radius)
        {
            double iarr = 1 / ((double)radius + radius + 1);

            for (int row = 0; row < sourceImage.Height; row++)
            {
                Color firstPixel    = sourceImage.GetPixel(0, row);
                Color lastPixel     = sourceImage.GetPixel(sourceImage.Width - 1, row);
                int   cumRedValue   = (radius + 1) * firstPixel.R;
                int   cumGreenValue = (radius + 1) * firstPixel.G;
                int   cumBlueValue  = (radius + 1) * firstPixel.B;

                int currentLastColIndex   = 0;      // li
                int currentRadiusColIndex = radius; // ri

                for (int col = 0; col < radius; col++)
                {
                    Color chosenPixel = sourceImage.GetPixel(col, row);
                    cumRedValue   += chosenPixel.R;
                    cumGreenValue += chosenPixel.G;
                    cumBlueValue  += chosenPixel.B;
                }

                for (int col = 0; col <= radius; col++)
                {
                    Color chosenPixel = sourceImage.GetPixel(currentRadiusColIndex, row);
                    cumRedValue   += chosenPixel.R - firstPixel.R;
                    cumGreenValue += chosenPixel.G - firstPixel.G;
                    cumBlueValue  += chosenPixel.B - firstPixel.B;
                    currentRadiusColIndex++;

                    outputImage.SetPixel(
                        col,
                        row,
                        Color.FromArgb(
                            (int)Math.Round(cumRedValue * iarr),
                            (int)Math.Round(cumGreenValue * iarr),
                            (int)Math.Round(cumBlueValue * iarr)
                            )
                        );
                }

                for (int col = radius + 1; col < sourceImage.Width - radius; col++)
                {
                    Color chosenRadiusPixel = sourceImage.GetPixel(currentRadiusColIndex, row);
                    Color chosenLastPixel   = sourceImage.GetPixel(currentLastColIndex, row);
                    cumRedValue   += chosenRadiusPixel.R - chosenLastPixel.R;
                    cumGreenValue += chosenRadiusPixel.G - chosenLastPixel.G;
                    cumBlueValue  += chosenRadiusPixel.B - chosenLastPixel.B;
                    currentRadiusColIndex++;
                    currentLastColIndex++;

                    outputImage.SetPixel(
                        col,
                        row,
                        Color.FromArgb(
                            (int)Math.Round(cumRedValue * iarr),
                            (int)Math.Round(cumGreenValue * iarr),
                            (int)Math.Round(cumBlueValue * iarr)
                            )
                        );
                }

                for (int col = sourceImage.Width - radius; col < sourceImage.Width; col++)
                {
                    Color chosenLastPixel = sourceImage.GetPixel(currentLastColIndex, row);
                    cumRedValue   += lastPixel.R - chosenLastPixel.R;
                    cumGreenValue += lastPixel.G - chosenLastPixel.G;
                    cumBlueValue  += lastPixel.B - chosenLastPixel.B;
                    currentLastColIndex++;

                    outputImage.SetPixel(
                        col,
                        row,
                        Color.FromArgb(
                            (int)Math.Round(cumRedValue * iarr),
                            (int)Math.Round(cumGreenValue * iarr),
                            (int)Math.Round(cumBlueValue * iarr)
                            )
                        );
                }
            }
        }
示例#9
0
        private static void PerformTotalBoxBlurAcc(WritableLockBitImage sourceImage, WritableLockBitImage outputImage, int radius)
        {
            double iarr = 1 / ((double)radius + radius + 1);

            for (int col = 0; col < sourceImage.Width; col++)
            {
                Color topPixel    = sourceImage.GetPixel(col, 0);
                Color bottomPixel = sourceImage.GetPixel(col, sourceImage.Height - 1);

                int cumRedValue   = (radius + 1) * topPixel.R;
                int cumGreenValue = (radius + 1) * topPixel.G;
                int cumBlueValue  = (radius + 1) * topPixel.B;

                for (int row = 0; row < radius; row++)
                {
                    Color chosenPixel = sourceImage.GetPixel(col, row);
                    cumRedValue   += chosenPixel.R;
                    cumGreenValue += chosenPixel.G;
                    cumBlueValue  += chosenPixel.B;
                }

                for (int row = 0; row <= radius; row++)
                {
                    Color chosenPixel = sourceImage.GetPixel(col, row + radius);
                    cumRedValue   += chosenPixel.R - topPixel.R;
                    cumGreenValue += chosenPixel.G - topPixel.G;
                    cumBlueValue  += chosenPixel.B - topPixel.B;

                    outputImage.SetPixel(
                        col,
                        row,
                        Color.FromArgb(
                            (int)Math.Round(cumRedValue * iarr),
                            (int)Math.Round(cumGreenValue * iarr),
                            (int)Math.Round(cumBlueValue * iarr)
                            )
                        );
                }

                for (int row = radius + 1; row < sourceImage.Height - radius; row++)
                {
                    Color radiusPixel  = sourceImage.GetPixel(col, radius + row);
                    Color laggingPixel = sourceImage.GetPixel(col, row - radius - 1);
                    cumRedValue   += radiusPixel.R - laggingPixel.R;
                    cumGreenValue += radiusPixel.G - laggingPixel.G;
                    cumBlueValue  += radiusPixel.B - laggingPixel.B;

                    outputImage.SetPixel(
                        col,
                        row,
                        Color.FromArgb(
                            (int)Math.Round(cumRedValue * iarr),
                            (int)Math.Round(cumGreenValue * iarr),
                            (int)Math.Round(cumBlueValue * iarr)
                            )
                        );
                }

                for (int row = sourceImage.Height - radius; row < sourceImage.Height; row++)
                {
                    Color laggingPixel = sourceImage.GetPixel(col, row - radius);
                    cumRedValue   += bottomPixel.R - laggingPixel.R;
                    cumGreenValue += bottomPixel.G - laggingPixel.G;
                    cumBlueValue  += bottomPixel.B - laggingPixel.B;

                    outputImage.SetPixel(
                        col,
                        row,
                        Color.FromArgb(
                            (int)Math.Round(cumRedValue * iarr),
                            (int)Math.Round(cumGreenValue * iarr),
                            (int)Math.Round(cumBlueValue * iarr)
                            )
                        );
                }
            }
        }