예제 #1
0
        public void fromRGB()
        {
            #region doc_rgb
            // This example shows how to convert to and from various
            // pixel representations. For example, let's say we start
            // with a RGB pixel with the value (24, 250, 153):
            RGB rgb = new RGB(red: 24, green: 250, blue: 153);

            // The value of this pixel in HSL format would be:
            HSL hsl = HSL.FromRGB(rgb);       // should be (154, 0.9576271, 0.5372549)

            // The value of this pixel in YCbCr format would be:
            YCbCr yCbCr = YCbCr.FromRGB(rgb); // should be (0.671929836, -0.0406815559, -0.412097245)

            // Note: we can also convert using casting:
            HSL   a = (HSL)rgb;
            YCbCr b = (YCbCr)rgb;
            #endregion

            Assert.AreEqual(24, rgb.Red);
            Assert.AreEqual(250, rgb.Green);
            Assert.AreEqual(153, rgb.Blue);
            Assert.AreEqual(255, rgb.Alpha);
            Assert.AreEqual(154, hsl.Hue);
            Assert.AreEqual(0.9576271, hsl.Saturation, 1e-6);
            Assert.AreEqual(0.5372549, hsl.Luminance, 1e-6);
            Assert.AreEqual(0.671929836, yCbCr.Y, 1e-6);
            Assert.AreEqual(-0.0406815559, yCbCr.Cb, 1e-6);
            Assert.AreEqual(-0.412097245, yCbCr.Cr, 1e-6);

            Assert.AreEqual(hsl, a);
            Assert.AreEqual(yCbCr, b);
        }
예제 #2
0
        public void fromHSL()
        {
            #region doc_hsl
            // This example shows how to convert to and from various
            // pixel representations. For example, let's say we start
            // with a HSL pixel with the value (123, 0.4, 0.8):
            HSL hsl = new HSL(hue: 123, saturation: 0.4f, luminance: 0.8f);

            // The value of this pixel in RGB format would be:
            RGB rgb = hsl.ToRGB();       // should be (183, 224, 185)

            // The value of this pixel in YCbCr format would be:
            YCbCr yCbCr = YCbCr.FromRGB(rgb); // should be (0.8128612, -0.0493462719, -0.0679121539)

            // Note: we can also convert using casting:
            RGB   a = (RGB)hsl;
            YCbCr b = (YCbCr)hsl;
            #endregion

            Assert.AreEqual(183, rgb.Red);
            Assert.AreEqual(224, rgb.Green);
            Assert.AreEqual(185, rgb.Blue);
            Assert.AreEqual(255, rgb.Alpha);
            Assert.AreEqual(123, hsl.Hue);
            Assert.AreEqual(0.4, hsl.Saturation, 1e-6);
            Assert.AreEqual(0.8, hsl.Luminance, 1e-6);
            Assert.AreEqual(0.8128612, yCbCr.Y, 1e-6);
            Assert.AreEqual(-0.0493462719, yCbCr.Cb, 1e-6);
            Assert.AreEqual(-0.0679121539, yCbCr.Cr, 1e-6);

            Assert.AreEqual(rgb, a);
            Assert.AreEqual(yCbCr, b);
        }
예제 #3
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        private unsafe void ApplyYCbCr(BitmapData bmData)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            float length = values.Length - 1;

            Parallel.For(0, height, y =>
            {
                int x, ystride, k;
                YCbCr ycbcr; RGB rgb;

                ystride = y * stride;

                for (x = 0; x < width; x++)
                {
                    k        = ystride + x * 4;
                    ycbcr    = YCbCr.FromRGB(p[k + 2], p[k + 1], p[k]);
                    ycbcr.Y  = values[(int)(ycbcr.Y * length)];
                    rgb      = ycbcr.ToRGB;
                    p[k + 2] = rgb.Red; p[k + 1] = rgb.Green; p[k] = rgb.Blue;
                }
            }
                         );

            return;
        }
예제 #4
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="bmSrc">Bitmap data</param>
        private unsafe void ApplyYCbCr(BitmapData bmData, BitmapData bmSrc)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer(), pSrc = (byte *)bmSrc.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            float length = values.GetLength(0) - 1;

            Parallel.For(0, height, j =>
            {
                YCbCr lumI; YCbCr lumIx; RGB rgb;
                int i, k, k1, k2, jstride = j * stride;

                for (i = 0; i < width; i++)
                {
                    k = jstride + i * 4; k1 = k + 1; k2 = k + 2;

                    lumI   = YCbCr.FromRGB(p[k2], p[k1], p[k]);
                    lumIx  = YCbCr.FromRGB(pSrc[k2], pSrc[k1], pSrc[k]);
                    lumI.Y = this.values[(int)(lumI.Y * length), (int)(lumIx.Y * length)];
                    rgb    = lumI.ToRGB;

                    p[k2] = rgb.Red; p[k1] = rgb.Green; p[k] = rgb.Blue;
                }
            }
                         );

            return;
        }
예제 #5
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap</param>
        public unsafe void Apply(BitmapData bmData)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;

            Parallel.For(0, height, j =>
            {
                YCbCr ycbcr; RGB rgb;
                int i, k, jstride = j * stride;

                for (i = 0; i < width; i++)
                {
                    k = jstride + i * 4;

                    ycbcr     = YCbCr.FromRGB(p[k + 2], p[k + 1], p[k + 0]);
                    ycbcr.Y  += y;
                    ycbcr.Cb += cb;
                    ycbcr.Cr += cr;
                    rgb       = ycbcr.ToRGB;

                    p[k + 0] = rgb.Blue;
                    p[k + 1] = rgb.Green;
                    p[k + 2] = rgb.Red;
                }
            }
                         );

            return;
        }
예제 #6
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="bmMax">Bitmap data</param>
        /// <param name="bmMin">Bitmap data</param>
        private unsafe void ApplyYCbCr(BitmapData bmData, BitmapData bmMax, BitmapData bmMin)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer();
            byte *pMax = (byte *)bmMax.Scan0.ToPointer();
            byte *pMin = (byte *)bmMin.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;

            float required = 1.0f - this.contrast;

            Parallel.For(0, height, j =>
            {
                YCbCr imag; YCbCr imax; YCbCr imin; RGB rgb;
                int i, k, k1, k2, jstride = j * stride;
                float mag, max, min;
                float num1, num2, num3;

                for (i = 0; i < width; i++)
                {
                    k = jstride + i * 4; k1 = k + 1; k2 = k + 2;

                    imag = YCbCr.FromRGB(p[k2], p[k1], p[k]);
                    imax = YCbCr.FromRGB(pMax[k2], pMax[k1], pMax[k]);
                    imin = YCbCr.FromRGB(pMin[k2], pMin[k1], pMin[k]);

                    mag = imag.Y;
                    max = imax.Y;
                    min = imin.Y;

                    num1 = max - min;

                    if (num1 < required)
                    {
                        num2 = min + (required - num1) * min / (num1 - 1f);
                        min  = Maths.Float(num2);
                        max  = Maths.Float(num2 + required);
                    }

                    num1 = max - min;
                    num3 = mag - min;

                    if (num1 > 0)
                    {
                        imag.Y = num3 / num1;
                        rgb    = imag.ToRGB;
                        p[k2]  = rgb.Red; p[k1] = rgb.Green; p[k] = rgb.Blue;
                    }
                }
            }
                         );
        }
예제 #7
0
        public mFilterYCbCrColor(wDomain Luminance, wDomain Blue, wDomain Red, bool isOut, Color fillColor)
        {
            Y         = Luminance;
            Cb        = Blue;
            Cr        = Red;
            IsOut     = isOut;
            FillColor = fillColor;

            BitmapType = mFilter.BitmapTypes.Rgb24bpp;

            Effect = new YCbCrFiltering(new Range((float)Y.T0, (float)Y.T1), new Range((float)Cb.T0, (float)Cb.T1), new Range((float)Cr.T0, (float)Cr.T1));

            Effect.FillOutsideRange = IsOut;
            Effect.FillColor        = YCbCr.FromRGB(new RGB(FillColor));
        }
예제 #8
0
        protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
        {
            int   num    = System.Drawing.Image.GetPixelFormatSize(sourceData.PixelFormat) / 8;
            int   width  = sourceData.Width;
            int   height = sourceData.Height;
            int   num2   = sourceData.Stride - width * num;
            int   num3   = destinationData.Stride - width;
            RGB   rGB    = new RGB();
            YCbCr yCbCr  = new YCbCr();
            byte *ptr    = (byte *)sourceData.ImageData.ToPointer();
            byte *ptr2   = (byte *)destinationData.ImageData.ToPointer();
            byte  b      = 0;

            for (int i = 0; i < height; i++)
            {
                int num4 = 0;
                while (num4 < width)
                {
                    rGB.Red   = ptr[2];
                    rGB.Green = ptr[1];
                    rGB.Blue  = *ptr;
                    YCbCr.FromRGB(rGB, yCbCr);
                    switch (channel)
                    {
                    case 0:
                        b = (byte)(yCbCr.Y * 255f);
                        break;

                    case 1:
                        b = (byte)(((double)yCbCr.Cb + 0.5) * 255.0);
                        break;

                    case 2:
                        b = (byte)(((double)yCbCr.Cr + 0.5) * 255.0);
                        break;
                    }
                    *ptr2 = b;
                    num4++;
                    ptr += num;
                    ptr2++;
                }
                ptr  += num2;
                ptr2 += num3;
            }
        }
예제 #9
0
        protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
        {
            int   num   = (image.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;
            int   left  = rect.Left;
            int   top   = rect.Top;
            int   num2  = left + rect.Width;
            int   num3  = top + rect.Height;
            int   num4  = image.Stride - rect.Width * num;
            RGB   rGB   = new RGB();
            YCbCr yCbCr = new YCbCr();
            byte *ptr   = (byte *)image.ImageData.ToPointer();

            ptr += top * image.Stride + left * num;
            for (int i = top; i < num3; i++)
            {
                int num5 = left;
                while (num5 < num2)
                {
                    bool flag = false;
                    rGB.Red   = ptr[2];
                    rGB.Green = ptr[1];
                    rGB.Blue  = *ptr;
                    YCbCr.FromRGB(rGB, yCbCr);
                    if (yCbCr.Y >= yRange.Min && yCbCr.Y <= yRange.Max && yCbCr.Cb >= cbRange.Min && yCbCr.Cb <= cbRange.Max && yCbCr.Cr >= crRange.Min && yCbCr.Cr <= crRange.Max)
                    {
                        if (!fillOutsideRange)
                        {
                            if (updateY)
                            {
                                yCbCr.Y = fillY;
                            }
                            if (updateCb)
                            {
                                yCbCr.Cb = fillCb;
                            }
                            if (updateCr)
                            {
                                yCbCr.Cr = fillCr;
                            }
                            flag = true;
                        }
                    }
                    else if (fillOutsideRange)
                    {
                        if (updateY)
                        {
                            yCbCr.Y = fillY;
                        }
                        if (updateCb)
                        {
                            yCbCr.Cb = fillCb;
                        }
                        if (updateCr)
                        {
                            yCbCr.Cr = fillCr;
                        }
                        flag = true;
                    }
                    if (flag)
                    {
                        YCbCr.ToRGB(yCbCr, rGB);
                        ptr[2] = rGB.Red;
                        ptr[1] = rGB.Green;
                        *ptr = rGB.Blue;
                    }
                    num5++;
                    ptr += num;
                }
                ptr += num4;
            }
        }
예제 #10
0
        public Image process(Image imageIn)
        {
            Color rgb   = new Color();
            YCbCr ycbcr = new YCbCr();

            float ky = 0, by = 0;
            float kcb = 0, bcb = 0;
            float kcr = 0, bcr = 0;

            // Y line parameters
            if (inY.Max != inY.Min)
            {
                ky = (outY.Max - outY.Min) / (inY.Max - inY.Min);
                by = outY.Min - ky * inY.Min;
            }
            // Cb line parameters
            if (inCb.Max != inCb.Min)
            {
                kcb = (outCb.Max - outCb.Min) / (inCb.Max - inCb.Min);
                bcb = outCb.Min - kcb * inCb.Min;
            }
            // Cr line parameters
            if (inCr.Max != inCr.Min)
            {
                kcr = (outCr.Max - outCr.Min) / (inCr.Max - inCr.Min);
                bcr = outCr.Min - kcr * inCr.Min;
            }

            for (int x = 0; x < imageIn.getWidth(); x++)
            {
                for (int y = 0; y < imageIn.getHeight(); y++)
                {
                    rgb.R = (byte)imageIn.getRComponent(x, y);
                    rgb.G = (byte)imageIn.getGComponent(x, y);
                    rgb.B = (byte)imageIn.getBComponent(x, y);

                    // convert to YCbCr
                    ycbcr = YCbCr.FromRGB(rgb, ycbcr);

                    // correct Y
                    if (ycbcr.Y >= inY.Max)
                    {
                        ycbcr.Y = outY.Max;
                    }
                    else if (ycbcr.Y <= inY.Min)
                    {
                        ycbcr.Y = outY.Min;
                    }
                    else
                    {
                        ycbcr.Y = ky * ycbcr.Y + by;
                    }

                    // correct Cb
                    if (ycbcr.Cb >= inCb.Max)
                    {
                        ycbcr.Cb = outCb.Max;
                    }
                    else if (ycbcr.Cb <= inCb.Min)
                    {
                        ycbcr.Cb = outCb.Min;
                    }
                    else
                    {
                        ycbcr.Cb = kcb * ycbcr.Cb + bcb;
                    }

                    // correct Cr
                    if (ycbcr.Cr >= inCr.Max)
                    {
                        ycbcr.Cr = outCr.Max;
                    }
                    else if (ycbcr.Cr <= inCr.Min)
                    {
                        ycbcr.Cr = outCr.Min;
                    }
                    else
                    {
                        ycbcr.Cr = kcr * ycbcr.Cr + bcr;
                    }

                    // convert back to RGB
                    rgb = YCbCr.ToRGB(ycbcr, rgb);

                    imageIn.setPixelColor(x, y, rgb.R, rgb.G, rgb.B);
                }
            }
            return(imageIn);
        }
예제 #11
0
        /// <summary>
        /// Converts a Bitmap to an YCbCr structure with or without alpha-channel.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="alpha">Alpha-channel</param>
        /// <returns>YCbCr structure array</returns>
        public unsafe static float[][,] ToYCbCr(this BitmapData bmData, bool alpha = false)
        {
            // params
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            byte *p = (byte *)bmData.Scan0.ToPointer();

            // matrices
            float[,] x = new float[height, width];
            float[,] y = new float[height, width];
            float[,] z = new float[height, width];

            // with alpha channel
            if (alpha)
            {
                float[,] a = new float[height, width];

                Parallel.For(0, height, j =>
                {
                    YCbCr mdl;

                    int i, k, jstride = j * stride;

                    for (i = 0; i < width; i++)
                    {
                        // shift:
                        k = jstride + i * 4;

                        mdl     = YCbCr.FromRGB(p[k + 2], p[k + 1], p[k + 0]);
                        x[j, i] = mdl.Y;
                        y[j, i] = mdl.Cb;
                        z[j, i] = mdl.Cr;
                        a[j, i] = p[k + 3] / 255.0f;
                    }
                });

                return(new float[][, ] {
                    x, y, z, a
                });
            }

            // without alpha channel
            Parallel.For(0, height, j =>
            {
                YCbCr mdl;

                int i, k, jstride = j * stride;

                for (i = 0; i < width; i++)
                {
                    // shift:
                    k = jstride + i * 4;

                    mdl     = YCbCr.FromRGB(p[k + 2], p[k + 1], p[k + 0]);
                    x[j, i] = mdl.Y;
                    y[j, i] = mdl.Cb;
                    z[j, i] = mdl.Cr;
                }
            });

            return(new float[][, ] {
                x, y, z
            });
        }
예제 #12
0
        private void MergeAndCompress_btn_Click(object sender, EventArgs e)
        {
            System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
            Bitmap sceneBitmap  = new Bitmap(SceneImage);
            Bitmap spriteBitmap = new Bitmap(SpriteImage);

            resultBitmap = sceneBitmap;

            int scenemidwidth   = sceneBitmap.Width / 2;
            int scenemidtheight = sceneBitmap.Height / 2;

            int Itstartx = scenemidwidth - (spriteBitmap.Width / 2);
            int Itstarty = scenemidtheight - (spriteBitmap.Height / 2);

            //textBox1.Text = Itstartx.ToString();
            //textBox2.Text = Itstarty.ToString();

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

                    if (spritecolor.G != 0)
                    {
                        resultBitmap.SetPixel(x + Itstartx, y + Itstarty, spritecolor);
                    }
                }
            }

            MergedPreviewBox.Image = resultBitmap.GetThumbnailImage(MergedPreviewBox.Width, MergedPreviewBox.Height, myCallback, IntPtr.Zero);



            //////////
            ///////////////MERGING    DONE
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////
///////////////Start of Compression part
////////////////////////////////////////////////////////////////////////////////////////////////////////////////


            //////////
            ///////////////Convert to YUV
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////



            //////////
            /////////////// add some pixels on both axis resulting multiple of 8
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            int zeroExtensionsX = 8 - (resultBitmap.Width % 8);
            int zeroExtensionsY = 8 - (resultBitmap.Height % 8);

            MyOwnYcbcr = new myYcBc(resultBitmap.Width + zeroExtensionsX, resultBitmap.Height + zeroExtensionsY);

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

                    Yuv ycrcb = new Yuv();

                    RGB rgbcolor = new RGB(resultcolor);

                    ycrcb.Yf = YCbCr.FromRGB(rgbcolor).Y * 255;

                    //4:2:0 sampling
                    if (y % 2 == 0 && x % 2 == 0)
                    {
                        ycrcb.Uf = YCbCr.FromRGB(rgbcolor).Cr * 255;
                        ycrcb.Vf = YCbCr.FromRGB(rgbcolor).Cb * 255;
                    }
                    else
                    {
                        ycrcb.Uf = 0;
                        ycrcb.Vf = 0;
                    }

                    MyOwnYcbcr.ycbcrArr[x, y] = ycrcb;
                }
            }

            //////////
            /////////////// Normalize to -128 <-> 127 range
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            for (int y = 0; y < MyOwnYcbcr.height; y++)
            {
                for (int x = 0; x < MyOwnYcbcr.width; x++)
                {
                    Yuv ycColorspaceEdit = MyOwnYcbcr.ycbcrArr[x, y];

                    ycColorspaceEdit.Ynorm = (int)((ycColorspaceEdit.Yf) - 128);

                    if (y % 2 == 0 && x % 2 == 0)
                    {
                        ycColorspaceEdit.Unorm = (int)((ycColorspaceEdit.Uf) - 128);
                        ycColorspaceEdit.Vnorm = (int)((ycColorspaceEdit.Vf) - 128);
                    }
                    else
                    {
                        ycColorspaceEdit.Unorm = (int)(ycColorspaceEdit.Uf);
                        ycColorspaceEdit.Vnorm = (int)(ycColorspaceEdit.Vf);
                    }

                    MyOwnYcbcr.ycbcrArr[x, y] = ycColorspaceEdit;
                }
            }

            //////////
            /////////////// DCT matrix Creation
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            //double[,]DCTmatrix;
            //DCTmatrix = new double[8, 8];
            //
            //for (int i = 0; i < 8; i++)
            //{
            //    for(int j = 0; j < 8; j++)
            //    {
            //        if(i == 0)
            //        {
            //            DCTmatrix[i,j] = 1 / Math.Sqrt(8);
            //        }
            //        else if(i > 0)
            //        {
            //            DCTmatrix[i, j] = Math.Sqrt( (2f/8f )) *  Math.Cos((((2 * j) + 1) * i * Math.PI) / (2 * 8)) ;
            //        }
            //    }
            //}


            //////////
            /////////////// DCT matrix Transposed
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            //double[,] DCTmatrixTransposed;
            //DCTmatrixTransposed = new double[8, 8];
            //
            //for (int i = 0; i < 8; i++)
            //{
            //    for (int j = 0; j < 8; j++)
            //    {
            //        DCTmatrixTransposed[i, j] = DCTmatrix[j, i];
            //    }
            //}

            //////////
            /////////////// 8 by 8 traversal and applying DCT to Merged picture
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            //double[,] DCTresult;
            //DCTresult = new double[8, 8];

            double[,] YtempDCT = new double[8, 8];
            double[,] UtempDCT = new double[8, 8];
            double[,] VtempDCT = new double[8, 8];


            for (int y = 0; y < MyOwnYcbcr.height; y += 8)
            {
                for (int x = 0; x < MyOwnYcbcr.width; x += 8)
                {
                    if (x <= MyOwnYcbcr.width - 8 && y <= MyOwnYcbcr.height - 8) //safeguard against out of bounds error
                    {
                        for (int ity = y; ity < y + 8; ity++)
                        {
                            for (int itx = x; itx < x + 8; itx++)
                            {
                                YtempDCT[ity - y, itx - x] = MyOwnYcbcr.ycbcrArr[itx, ity].Ynorm;
                                UtempDCT[ity - y, itx - x] = MyOwnYcbcr.ycbcrArr[itx, ity].Unorm;
                                VtempDCT[ity - y, itx - x] = MyOwnYcbcr.ycbcrArr[itx, ity].Vnorm;
                            }
                        }

                        CosineTransform.DCT(YtempDCT);
                        CosineTransform.DCT(UtempDCT);
                        CosineTransform.DCT(VtempDCT);

                        for (int ity = y; ity < y + 8; ity++)
                        {
                            for (int itx = x; itx < x + 8; itx++)
                            {
                                MyOwnYcbcr.ycbcrArr[itx, ity].Ydct = YtempDCT[ity - y, itx - x];
                                MyOwnYcbcr.ycbcrArr[itx, ity].Udct = UtempDCT[ity - y, itx - x];
                                MyOwnYcbcr.ycbcrArr[itx, ity].Vdct = VtempDCT[ity - y, itx - x];
                            }
                        }
                    }
                }
            }


            //default quality value of 50;

            int[,] QuantMatrix;
            QuantMatrix = new int[8, 8] {
                { 16, 11, 10, 16, 24, 40, 51, 61 },
                { 12, 12, 14, 19, 26, 58, 60, 55 },
                { 14, 13, 16, 24, 40, 57, 69, 56 },
                { 14, 17, 22, 29, 51, 87, 80, 62 },
                { 18, 22, 37, 56, 68, 109, 103, 77 },
                { 24, 35, 55, 64, 81, 104, 113, 92 },
                { 49, 64, 78, 87, 103, 121, 120, 101 },
                { 72, 92, 95, 98, 112, 100, 103, 99 },
            };

            // changing quality value
            if (QuantizationQuality != 50)
            {
                for (int x = 0; x < 8; x++)
                {
                    for (int y = 0; y < 8; y++)
                    {
                        if (QuantizationQuality > 50)
                        {
                            QuantMatrix[x, y] = (int)(QuantMatrix[x, y] * ((float)(100 - QuantizationQuality) / 50f));
                            if (QuantMatrix[x, y] > 255)
                            {
                                QuantMatrix[x, y] = 255;
                            }
                            if (QuantMatrix[x, y] == 0)
                            {
                                QuantMatrix[x, y] = 1;
                            }
                        }
                        else if (QuantizationQuality < 50)
                        {
                            QuantMatrix[x, y] = QuantMatrix[x, y] * (50 / QuantizationQuality);
                            if (QuantMatrix[x, y] > 255)
                            {
                                QuantMatrix[x, y] = 255;
                            }
                            else if (QuantMatrix[x, y] == 0)
                            {
                                QuantMatrix[x, y] = 1;
                            }
                        }
                    }
                }
            }


            //////////
            /////////////// 8 by 8 traversal and appyling Quantization
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////


            for (int y = 0; y < MyOwnYcbcr.height; y += 8)
            {
                for (int x = 0; x < MyOwnYcbcr.width; x += 8)
                {
                    for (int ity = y; ity < y + 8; ity++)
                    {
                        for (int itx = x; itx < x + 8; itx++)
                        {
                            if (itx < MyOwnYcbcr.width && ity < MyOwnYcbcr.height)
                            {
                                MyOwnYcbcr.ycbcrArr[itx, ity].Yquant = (int)Math.Round(MyOwnYcbcr.ycbcrArr[itx, ity].Ydct / QuantMatrix[itx - x, ity - y]);
                                MyOwnYcbcr.ycbcrArr[itx, ity].Uquant = (int)Math.Round(MyOwnYcbcr.ycbcrArr[itx, ity].Udct / QuantMatrix[itx - x, ity - y]);
                                MyOwnYcbcr.ycbcrArr[itx, ity].Vquant = (int)Math.Round(MyOwnYcbcr.ycbcrArr[itx, ity].Vdct / QuantMatrix[itx - x, ity - y]);
                            }
                        }
                    }
                }
            }

            //////////
            /////////////// 8 by 8 traversal and appyling ZIG ZAG
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////


            for (int y = 0; y < MyOwnYcbcr.height; y += 8)
            {
                for (int x = 0; x < MyOwnYcbcr.width; x += 8)
                {
                    if (x <= MyOwnYcbcr.width - 8 && y <= MyOwnYcbcr.height - 8) //safeguard against out of bounds error
                    {
                        int[,] YZbuffer = new int[8, 8];
                        int[,] UZbuffer = new int[8, 8];
                        int[,] VZbuffer = new int[8, 8];
                        // make a copy in buffer so that zigzag can copy it over to the original.

                        for (int buffery = y; buffery < y + 8; buffery++)
                        {
                            for (int bufferx = x; bufferx < x + 8; bufferx++)
                            {
                                YZbuffer[bufferx - x, buffery - y] = MyOwnYcbcr.ycbcrArr[bufferx, buffery].Yquant;
                                UZbuffer[bufferx - x, buffery - y] = MyOwnYcbcr.ycbcrArr[bufferx, buffery].Uquant;
                                VZbuffer[bufferx - x, buffery - y] = MyOwnYcbcr.ycbcrArr[bufferx, buffery].Vquant;
                            }
                        }

                        // copy zigzag wise from the buffer to the original

                        for (int ity = y; ity < y + 8; ity++)
                        {
                            for (int itx = x; itx < x + 8; itx++)
                            {
                                if (itx < MyOwnYcbcr.width && ity < MyOwnYcbcr.height)
                                {
                                    Coords Targetcoords;

                                    Targetcoords = ZZtraverseValue(itx - x, ity - y);

                                    MyOwnYcbcr.zigzagY.Add(YZbuffer[Targetcoords.xvalue, Targetcoords.yvalue]);
                                    MyOwnYcbcr.zigzagU.Add(UZbuffer[Targetcoords.xvalue, Targetcoords.yvalue]);
                                    MyOwnYcbcr.zigzagV.Add(VZbuffer[Targetcoords.xvalue, Targetcoords.yvalue]);
                                }
                            }
                        }
                    }
                }
            }



            Coords testcoords;

            testcoords.xvalue = 920;
            testcoords.yvalue = 0;

            for (int y = testcoords.yvalue; y < testcoords.yvalue + 8; y++)
            {
                for (int x = testcoords.xvalue; x < testcoords.xvalue + 8; x++)
                {
                    Matrixviewer.Rows[y - testcoords.yvalue].Cells[x - testcoords.xvalue].Value = MyOwnYcbcr.ycbcrArr[x, y].Yquant;
                    //Matrixviewer.Rows[x].Cells[y].Value = QuantMatrix[x, y];
                    //Matrixviewer.Rows[x].Cells[y].Value = testoutputmatrix[x, y];
                }
            }

            Merged_width_txtbx.Text  = MyOwnYcbcr.width.ToString();
            Merged_height_txtbx.Text = MyOwnYcbcr.height.ToString();

            textBox1.Text = MyOwnYcbcr.zigzagU.Count.ToString();
            textBox2.Text = (MyOwnYcbcr.width * MyOwnYcbcr.height).ToString();

            textBox3.Text = MyOwnYcbcr.zigzagV[7360].ToString();

            //for (int y = 0; y < 8; y++)
            //{
            //    for (int x = 0; x < 8; x++)
            //    {
            //        Matrixviewer.Rows[x].Cells[y].Value = testdata[x,y];
            //        //Matrixviewer.Rows[x].Cells[y].Value = QuantMatrix[x, y];
            //        //Matrixviewer.Rows[x].Cells[y].Value = testoutputmatrix[x, y];
            //    }
            //}


            //for (int x = 0; x < 8; x++)
            //{
            //    for (int y = 0; y < 8; y++)
            //    {
            //        Matrixviewer.Rows[y].Cells[x].Value = MyOwnYcbcr.ycbcrArr[x, y].Y;
            //    }
            //}
        }
예제 #13
0
        protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
        {
            int   num   = System.Drawing.Image.GetPixelFormatSize(image.PixelFormat) / 8;
            int   left  = rect.Left;
            int   top   = rect.Top;
            int   num2  = left + rect.Width;
            int   num3  = top + rect.Height;
            int   num4  = image.Stride - rect.Width * num;
            RGB   rGB   = new RGB();
            YCbCr yCbCr = new YCbCr();
            float num5  = 0f;
            float num6  = 0f;
            float num7  = 0f;
            float num8  = 0f;
            float num9  = 0f;
            float num10 = 0f;

            if (inY.Max != inY.Min)
            {
                num5 = (outY.Max - outY.Min) / (inY.Max - inY.Min);
                num6 = outY.Min - num5 * inY.Min;
            }
            if (inCb.Max != inCb.Min)
            {
                num7 = (outCb.Max - outCb.Min) / (inCb.Max - inCb.Min);
                num8 = outCb.Min - num7 * inCb.Min;
            }
            if (inCr.Max != inCr.Min)
            {
                num9  = (outCr.Max - outCr.Min) / (inCr.Max - inCr.Min);
                num10 = outCr.Min - num9 * inCr.Min;
            }
            byte *ptr = (byte *)image.ImageData.ToPointer();

            ptr += top * image.Stride + left * num;
            for (int i = top; i < num3; i++)
            {
                int num11 = left;
                while (num11 < num2)
                {
                    rGB.Red   = ptr[2];
                    rGB.Green = ptr[1];
                    rGB.Blue  = *ptr;
                    YCbCr.FromRGB(rGB, yCbCr);
                    if (yCbCr.Y >= inY.Max)
                    {
                        yCbCr.Y = outY.Max;
                    }
                    else if (yCbCr.Y <= inY.Min)
                    {
                        yCbCr.Y = outY.Min;
                    }
                    else
                    {
                        yCbCr.Y = num5 * yCbCr.Y + num6;
                    }
                    if (yCbCr.Cb >= inCb.Max)
                    {
                        yCbCr.Cb = outCb.Max;
                    }
                    else if (yCbCr.Cb <= inCb.Min)
                    {
                        yCbCr.Cb = outCb.Min;
                    }
                    else
                    {
                        yCbCr.Cb = num7 * yCbCr.Cb + num8;
                    }
                    if (yCbCr.Cr >= inCr.Max)
                    {
                        yCbCr.Cr = outCr.Max;
                    }
                    else if (yCbCr.Cr <= inCr.Min)
                    {
                        yCbCr.Cr = outCr.Min;
                    }
                    else
                    {
                        yCbCr.Cr = num9 * yCbCr.Cr + num10;
                    }
                    YCbCr.ToRGB(yCbCr, rGB);
                    ptr[2] = rGB.Red;
                    ptr[1] = rGB.Green;
                    *ptr = rGB.Blue;
                    num11++;
                    ptr += num;
                }
                ptr += num4;
            }
        }
예제 #14
0
        protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
        {
            int        num        = System.Drawing.Image.GetPixelFormatSize(image.PixelFormat) / 8;
            int        width      = image.Width;
            int        height     = image.Height;
            int        left       = rect.Left;
            int        top        = rect.Top;
            int        num2       = left + rect.Width;
            int        num3       = top + rect.Height;
            int        num4       = image.Stride - rect.Width * num;
            BitmapData bitmapData = null;
            int        num5       = 0;
            byte *     ptr;

            if (channelImage != null)
            {
                if (width != channelImage.Width || height != channelImage.Height)
                {
                    throw new InvalidImagePropertiesException("Channel image size does not match source image size.");
                }
                bitmapData = channelImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
                ptr        = (byte *)bitmapData.Scan0.ToPointer();
                num5       = bitmapData.Stride;
            }
            else
            {
                if (width != unmanagedChannelImage.Width || height != unmanagedChannelImage.Height)
                {
                    throw new InvalidImagePropertiesException("Channel image size does not match source image size.");
                }
                ptr  = (byte *)(void *)unmanagedChannelImage.ImageData;
                num5 = unmanagedChannelImage.Stride;
            }
            int   num6  = num5 - rect.Width;
            RGB   rGB   = new RGB();
            YCbCr yCbCr = new YCbCr();
            byte *ptr2  = (byte *)image.ImageData.ToPointer();

            ptr2 += top * image.Stride + left * num;
            ptr  += top * num5 + left;
            for (int i = top; i < num3; i++)
            {
                int num7 = left;
                while (num7 < num2)
                {
                    rGB.Red   = ptr2[2];
                    rGB.Green = ptr2[1];
                    rGB.Blue  = *ptr2;
                    YCbCr.FromRGB(rGB, yCbCr);
                    switch (channel)
                    {
                    case 0:
                        yCbCr.Y = (float)(int)(*ptr) / 255f;
                        break;

                    case 1:
                        yCbCr.Cb = (float)(int)(*ptr) / 255f - 0.5f;
                        break;

                    case 2:
                        yCbCr.Cr = (float)(int)(*ptr) / 255f - 0.5f;
                        break;
                    }
                    YCbCr.ToRGB(yCbCr, rGB);
                    ptr2[2] = rGB.Red;
                    ptr2[1] = rGB.Green;
                    *ptr2 = rGB.Blue;
                    num7++;
                    ptr2 += num;
                    ptr++;
                }
                ptr2 += num4;
                ptr  += num6;
            }
            if (bitmapData != null)
            {
                channelImage.UnlockBits(bitmapData);
            }
        }