Exemplo n.º 1
0
        public static unsafe UnmanagedImage GetChannelAsImage(this UnmanagedImage image, RGBA channel)
        {
            var c  = (short)channel;
            var pb = image.GetPixelFormatSizeInBytes();

            if (c < 0 ||
                c >= pb)
            {
                throw new ArgumentOutOfRangeException(nameof(c));
            }

            var wb  = pb * image.Width;
            var pad = image.Stride - wb;

            var result = UnmanagedImage.Create(image.Width, image.Height, PixelFormat.Format8bppIndexed);

            var d = (byte *)image.ImageData + c;
            var e = (byte *)result.ImageData;

            for (var dT0 = d + (image.Stride * image.Height); d < dT0; d += pad)
            {
                for (var dToLine = d + wb; d < dToLine; d += pb, e++)
                {
                    *e = *d;
                }
            }

            return(result);
        }
Exemplo n.º 2
0
        public static unsafe int[] Subtract(this UnmanagedImage image1, [NotNull] UnmanagedImage image2)
        {
            ImageCheck.CheckSameSize(image1, image2);

            var w   = image1.Width;
            var h   = image1.Height;
            var s   = image1.Stride;
            var dt1 = (byte *)image1.ImageData;
            var dt2 = (byte *)image2.ImageData;

            var dt1To  = dt1 + (h * s);
            var wb     = w * image1.GetPixelFormatSizeInBytes();
            var result = new int[wb * h];
            var j      = 0;

            for (; dt1 < dt1To; dt1 += s, dt2 += s)
            {
                for (var i = 0; i < wb; i++)
                {
                    result[j++] = dt1[i] - dt2[i];
                }
            }

            return(result);
        }
Exemplo n.º 3
0
        /// <summary>
        ///   Converts a rgb image to an rgba image.
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public static unsafe float[] ToFloats(UnmanagedImage image)
        {
            const float alpha = 255;
            const int   pwR   = 4;
            var         pwI   = image.GetPixelFormatSizeInBytes();

            var w      = image.Width;
            var h      = image.Height;
            var s      = w * 4;
            var result = new float[s * h];

            var dtI = (byte *)image.ImageData;

            var wpR   = w * pwR;
            var paddI = image.Stride - (w * pwI);

            var i = 0;

            switch (image.PixelFormat)
            {
            case PixelFormat.Format32bppRgb:
            case PixelFormat.Format24bppRgb:
                for (var dtrTo = h * s; i < dtrTo; dtI += paddI)
                {
                    for (var dtrLineTo = i + wpR; i < dtrLineTo; dtI += pwI, i += pwR)
                    {
                        result[i + RGB_R_CL] = dtI[RGB_R];
                        result[i + RGB_G_CL] = dtI[RGB_G];
                        result[i + RGB_B_CL] = dtI[RGB_B];
                        result[i + RGB_A_CL] = alpha;
                    }
                }

                break;

            case PixelFormat.Format32bppArgb:
                for (var dtrTo = h * s; i < dtrTo; dtI += paddI)
                {
                    for (var dtrLineTo = i + wpR; i < dtrLineTo; dtI += pwI, i += pwR)
                    {
                        result[i + RGB_R_CL] = dtI[RGB_R];
                        result[i + RGB_G_CL] = dtI[RGB_G];
                        result[i + RGB_B_CL] = dtI[RGB_B];
                        result[i + RGB_A_CL] = dtI[RGB_A];
                    }
                }

                break;

            default:
                throw new BadImageFormatException(nameof(image));
            }

            return(result);
        }
Exemplo n.º 4
0
        private static unsafe void IntegrateImage(UnmanagedImage srcImg,
                                                  float[] sumData,
                                                  float xFocus,
                                                  float yFocus,
                                                  float norm)
        {
            var srcFactorX0 = ((float)Math.Floor(xFocus) + 1) - xFocus;
            var srcFactorY0 = ((float)Math.Floor(yFocus) + 1) - yFocus;

            var src00 = srcFactorX0 * srcFactorY0 * norm;
            var src10 = (1 - srcFactorX0) * srcFactorY0 * norm;
            var src01 = srcFactorX0 * (1 - srcFactorY0) * norm;
            var src11 = (1 - srcFactorX0) * (1 - srcFactorY0) * norm;

            var pixelBytes = srcImg.GetPixelFormatSizeInBytes();
            var stride     = srcImg.Stride;

            var d = (byte *)srcImg.ImageData;

            var desXMin = Math.Max(-(int)Math.Ceiling(xFocus) + 1, 0);
            var desYMin = Math.Max(-(int)Math.Ceiling(yFocus) + 1, 0);
            var desXMax = (int)Math.Ceiling(srcImg.Width - Math.Max(xFocus, -1) - 1);
            var desYMax = (int)Math.Ceiling(srcImg.Height - Math.Max(yFocus, -1) - 1);
            var desIMin = desXMin * pixelBytes;
            var desIMax = desXMax * pixelBytes;

            var srcI = ((int)Math.Floor(yFocus) * stride) + ((int)Math.Floor(xFocus) * pixelBytes);

            Parallel.For(
                desYMin,
                desYMax,
                Preferences.PoOne,
                y => {
                int iEx;
                var i = (iEx = y * stride) + desIMin;
                iEx  += desIMax;
                for (; i < iEx; i += pixelBytes)
                {
                    var srcI0 = i + srcI;
                    var srcI1 = srcI0 + pixelBytes;
                    var srcI2 = srcI0 + stride;
                    var srcI3 = srcI2 + pixelBytes;

                    for (var bit = 0; bit < pixelBytes; bit++)
                    {
                        sumData[i + bit] += (src00 * d[srcI0 + bit]) +
                                            (src10 * d[srcI1 + bit]) +
                                            (src01 * d[srcI2 + bit]) +
                                            (src11 * d[srcI3 + bit]);
                    }
                }
            }
                );
        }
Exemplo n.º 5
0
        private static unsafe void DoRgb2Lab(UnmanagedImage srcImage, UnmanagedImage dstImage)
        {
            var pb       = srcImage.GetPixelFormatSizeInBytes();
            var hasAlpha = pb == 4;

            var srcPtr = (byte *)srcImage.ImageData;
            var dstPtr = (byte *)dstImage.ImageData;

            var line = srcImage.Width * pb;
            var padd = srcImage.Stride - line;

            if (hasAlpha)
            {
                for (var srcPtrTo = srcPtr + (srcImage.Stride * srcImage.Height);
                     srcPtr < srcPtrTo;
                     srcPtr += padd, dstPtr += padd)
                {
                    for (var srcLineTo = srcPtr + line; srcPtr < srcLineTo; srcPtr += pb, dstPtr += pb)
                    {
                        Rgb2Lab(
                            srcPtr[RGB_R],
                            srcPtr[RGB_G],
                            srcPtr[RGB_B],
                            out dstPtr[LAB_L],
                            out dstPtr[LAB_A],
                            out dstPtr[LAB_B]
                            );
                        dstPtr[RGB_A] = srcPtr[RGB_A];
                    }
                }
            }
            else
            {
                for (var srcPtrTo = srcPtr + (srcImage.Stride * srcImage.Height);
                     srcPtr < srcPtrTo;
                     srcPtr += padd, dstPtr += padd)
                {
                    for (var srcLineTo = srcPtr + line; srcPtr < srcLineTo; srcPtr += pb, dstPtr += pb)
                    {
                        Rgb2Lab(
                            srcPtr[RGB_R],
                            srcPtr[RGB_G],
                            srcPtr[RGB_B],
                            out dstPtr[LAB_L],
                            out dstPtr[LAB_A],
                            out dstPtr[LAB_B]
                            );
                    }
                }
            }
        }
Exemplo n.º 6
0
        public static unsafe void CopyFrom(this UnmanagedImage image, float[] src, float factor)
        {
            var ptr  = (byte *)image.ImageData;
            var l    = image.Width + image.GetPixelFormatSizeInBytes();
            var n    = Math.Min(l * image.Height, src.Length);
            var padd = image.Stride - l;

            for (var i = 0; i < n;)
            {
                ptr[i++] = (src[i] * factor).ToBase256();
                if (i % l == 0) // shift pointer by it's padding width at the end of line
                {
                    ptr += padd;
                }
            }
        }
Exemplo n.º 7
0
        public static void Draw(this UnmanagedImage thisImage, UnmanagedImage srcImage, int x, int y)
        {
            if (srcImage.PixelFormat != thisImage.PixelFormat)
            {
                throw new InvalidOperationException(
                          "Different image formats: '" + srcImage.PixelFormat + "' and '" + thisImage.PixelFormat + "'."
                          );
            }

            var pixelBytes = srcImage.GetPixelFormatSizeInBytes();

            x *= pixelBytes;
            var sS            = srcImage.Stride;
            var sD            = thisImage.Stride;
            var nSrc          = Math.Min(srcImage.Height, thisImage.Height - y) * sS; // bottom clip
            var srcClipStride = Math.Min(
                srcImage.Width * pixelBytes,
                (thisImage.Width * pixelBytes) - x
                );                         // right clip
            var iSrc = 0;
            var iDst = x + ((y - 1) * sD); //y-1 because increment before use

            if (y < 0)
            {
                // top clip
                iSrc -= y * sS;
                iDst -= y * sD;
            }

            if (x < 0)
            {
                // left clip
                srcClipStride += x;
                iSrc          -= x;
                //nSrc -= x;  // TODO: required?
                iDst -= x; // x = 0
            }

            Debug.Assert(srcClipStride >= 0 && iSrc < nSrc, "There is always a intersect.");
            var d = srcImage.ImageData;
            var e = thisImage.ImageData;

            for (; iSrc < nSrc; iSrc += sS)
            {
                MarshalX.Copy(e + (iDst += sD), d + iSrc, srcClipStride);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        ///   Converts a rgb image to an rgba image.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="outImage"></param>
        /// <returns></returns>
        public static unsafe void CreateFromFloats(float[] data, UnmanagedImage outImage)
        {
            const int pwI = 4;
            var       w   = outImage.Width;
            var       h   = outImage.Height;
            var       sDt = w * 4;

            var pwR = outImage.GetPixelFormatSizeInBytes();
            var dtR = (byte *)outImage.ImageData;

            var wpI   = w * pwI;
            var paddR = outImage.Stride - (w * pwR);

            if (pwR == 4) // apply alpha to?
            {
                for (int i = 0,
                     iTo = h * sDt;
                     i < iTo;
                     dtR += paddR)
                {
                    for (var iToLine = i + wpI; i < iToLine; dtR += pwR, i += pwI)
                    {
                        dtR[RGB_R] = data[i + RGB_R_CL].ClampToByte();
                        dtR[RGB_G] = data[i + RGB_G_CL].ClampToByte();
                        dtR[RGB_B] = data[i + RGB_B_CL].ClampToByte();
                        dtR[RGB_A] = data[i + RGB_A_CL].ClampToByte();
                    }
                }
            }
            else
            {
                for (int i = 0,
                     iTo = h * sDt;
                     i < iTo;
                     dtR += paddR)
                {
                    for (var iToLine = i + wpI; i < iToLine; dtR += pwR, i += pwI)
                    {
                        dtR[RGB_R] = data[i + RGB_R_CL].ClampToByte();
                        dtR[RGB_G] = data[i + RGB_G_CL].ClampToByte();
                        dtR[RGB_B] = data[i + RGB_B_CL].ClampToByte();
                    }
                }
            }
        }
Exemplo n.º 9
0
        public static unsafe void Colorize(UnmanagedImage image, Rectangle rect, int usedChannel)
        {
            var pb = image.GetPixelFormatSizeInBytes();

            if (usedChannel < 0 ||
                usedChannel >= pb)
            {
                throw new ArgumentException(nameof(usedChannel));
            }

            var d  = (byte *)image.ImageData + (rect.Y * image.Stride) + (rect.X * pb) + usedChannel;
            var wd = Math.Min(rect.Width, image.Width - rect.X) * pb;

            var dPad = image.Stride - wd;

            for (var dTo = d + (Math.Min(rect.Height, image.Height - rect.Y) * image.Stride); d < dTo; d += dPad)
            {
                for (var dToLn = d + wd; d < dToLn; d += pb)
                {
                    *d = byte.MaxValue;
                }
            }
        }
Exemplo n.º 10
0
        public static void CopyTo(this UnmanagedImage srcImage, ref byte[] dstArray)
        {
            var wb = srcImage.Width * srcImage.GetPixelFormatSizeInBytes();
            var s  = srcImage.Stride;
            var nj = wb * srcImage.Height;

            if (dstArray == null ||
                dstArray.Length < nj)
            {
                dstArray = new byte[nj];
            }

            int i = 0,
                j = 0;

            if (nj >= dstArray.Length)
            {
                nj -= wb;
                for (; j < nj; i += s, j += wb)
                {
                    Marshal.Copy(srcImage.ImageData + i, dstArray, j, wb);
                }

                Marshal.Copy(srcImage.ImageData + i, dstArray, j, dstArray.Length - j);
            }
            else
            {
                var ni = s * (srcImage.Height - 1);
                for (; i < ni; i += s, j += wb)
                {
                    Marshal.Copy(srcImage.ImageData + i, dstArray, j, wb);
                }

                Marshal.Copy(srcImage.ImageData + i, dstArray, j, i = (ni + wb) - i);
                Array.Clear(dstArray, j += i, dstArray.Length - j);
            }
        }
Exemplo n.º 11
0
        public static unsafe void Lab2Rgb(UnmanagedImage srcImage, UnmanagedImage dstImage)
        {
            if (srcImage == null ||
                dstImage == null)
            {
                throw new NullReferenceException(srcImage == null ? nameof(srcImage) : nameof(dstImage));
            }

            var bytesPerPixel = srcImage.GetPixelFormatSizeInBytes();
            var hasAlpha      = bytesPerPixel == 4;

            if (bytesPerPixel != 3 &&
                !hasAlpha)
            {
                throw new NotSupportedException(nameof(bytesPerPixel) + " != 4");
            }

            var srcPtr = (byte *)srcImage.ImageData;
            var dstPtr = (byte *)dstImage.ImageData;

            var line = srcImage.Width * bytesPerPixel;
            var padd = srcImage.Stride - line;

            if (hasAlpha)
            {
                for (var srcPtrTo = srcPtr + (srcImage.Stride * srcImage.Height);
                     srcPtr < srcPtrTo;
                     srcPtr += padd, dstPtr += padd)
                {
                    for (var srcLineTo = srcPtr + line; srcPtr < srcLineTo; srcPtr += bytesPerPixel, dstPtr += bytesPerPixel)
                    {
                        Lab2Rgb(
                            srcPtr[LAB_L],
                            srcPtr[LAB_A],
                            srcPtr[LAB_B],
                            out dstPtr[RGB_R],
                            out dstPtr[RGB_G],
                            out dstPtr[RGB_B]
                            );
                        dstPtr[RGB_A] = srcPtr[RGB_A];
                    }
                }
            }
            else
            {
                for (var srcPtrTo = srcPtr + (srcImage.Stride * srcImage.Height);
                     srcPtr < srcPtrTo;
                     srcPtr += padd, dstPtr += padd)
                {
                    for (var srcLineTo = srcPtr + line; srcPtr < srcLineTo; srcPtr += bytesPerPixel, dstPtr += bytesPerPixel)
                    {
                        Lab2Rgb(
                            srcPtr[LAB_L],
                            srcPtr[LAB_A],
                            srcPtr[LAB_B],
                            out dstPtr[RGB_R],
                            out dstPtr[RGB_G],
                            out dstPtr[RGB_B]
                            );
                    }
                }
            }
        }
Exemplo n.º 12
0
 public static int GetLineForward(this UnmanagedImage image) =>
 image.Stride - (image.Width * image.GetPixelFormatSizeInBytes());
Exemplo n.º 13
0
 public static int GetNumBytes(this UnmanagedImage image) =>
 image.Width * image.GetPixelFormatSizeInBytes() * image.Height;
Exemplo n.º 14
0
 public static int GetBytesPerPixel(this UnmanagedImage image) => image.GetPixelFormatSizeInBytes();
Exemplo n.º 15
0
        static unsafe void VerticalBoxBlur(ref UnmanagedImage image, Rectangle rect, IntRange kernelSizeRange)
        {
            int pixelSize = image.GetPixelFormatSizeInBytes();

            int startY = rect.Top;
            int stopY  = startY + rect.Height;

            int startX = rect.Left * pixelSize;
            int stopX  = startX + rect.Width * pixelSize;

            byte *basePtr = (byte *)image.ImageData.ToPointer();

            if (image.PixelFormat == PixelFormat.Format8bppIndexed ||
                image.PixelFormat == PixelFormat.Format24bppRgb ||
                image.PixelFormat == PixelFormat.Format32bppArgb ||
                image.PixelFormat == PixelFormat.Format32bppRgb)
            {
                int offset = image.Stride - (stopX - startX);

                // align pointer to the first pixel to process
                var ptr = basePtr + (startY * image.Stride + rect.Left * pixelSize);

                for (int y = startY; y < stopY; y++)
                {
                    for (int x = startX; x < stopX; x++, ptr++)
                    {
                        int sum = 0;

                        for (int yFilter = kernelSizeRange.Min; yFilter < kernelSizeRange.Max; yFilter++)
                        {
                            int yBound = y + yFilter;

                            //Only if in bounds
                            if (yBound < 0 || yBound >= image.Height)
                            {
                                continue;
                            }

                            sum += ptr[yFilter * image.Stride];
                        }

                        *ptr = (byte)(sum / kernelSizeRange.Length);
                    }

                    ptr += offset;
                }
            }
            else // 16bpp per channel (ushort*)
            {
                // align pointer to the first pixel to process
                basePtr += (startY * image.Stride + rect.Left * pixelSize * 2);

                for (int y = startY; y < stopY; y++)
                {
                    ushort *ptr = (ushort *)(basePtr);

                    for (int x = startX; x < stopX; x++, ptr++)
                    {
                        int sum = 0;

                        for (int yFilter = kernelSizeRange.Min; yFilter < kernelSizeRange.Max; yFilter++)
                        {
                            int yBound = y + yFilter;

                            //Only if in bounds
                            if (yBound < 0 || yBound >= image.Height)
                            {
                                continue;
                            }

                            sum += ptr[yFilter * image.Stride / 2];
                        }

                        *ptr = (ushort)(sum / kernelSizeRange.Length);
                    }

                    basePtr += image.Stride;
                }
            }
        }