Example #1
0
        /// <summary>
        /// Merges two images taking into consideration their alpha values.
        /// </summary>
        /// <param name="bmpBg">The background Image</param>
        /// <param name="bmpTop">The image that goes on top of the background</param>
        /// <param name="xBg">Left corner position of background</param>
        /// <param name="yBg">Top corner position of the background</param>
        /// <param name="xTop">Left corner position of the top image</param>
        /// <param name="yTop">Top corner position of the top image</param>
        /// <returns>Returns an interface to the image</returns>
        IImageAdapterUnmanaged IImageAdapterUnmanaged.Merge(IImageAdapterUnmanaged bmpBg, IImageAdapterUnmanaged bmpTop, int xBg, int yBg, int xTop, int yTop)
        {
            System.Diagnostics.Debug.WriteLine("Merge() started");
#if DEBUG
            ImageUtility.ToImageFile(bmpBg, System.IO.Path.Combine(System.IO.Path.GetTempPath(), "Before_Merge_Bg.png"));
            ImageUtility.ToImageFile(bmpTop, System.IO.Path.Combine(System.IO.Path.GetTempPath(), "Before_Merge_Top.png"));
#endif // debug

#if DEBUG
            ImageUtility.ToImageFile((IImageAdapter)bmpBg, System.IO.Path.Combine(System.IO.Path.GetTempPath(), "Merge_BgImage.bmp"));
            ImageUtility.ToImageFile((IImageAdapter)bmpTop, System.IO.Path.Combine(System.IO.Path.GetTempPath(), "Merge_TopImage.bmp"));
#endif // DEBUG

            Rectangle rBg  = new Rectangle(xBg, yBg, bmpBg.Width, bmpBg.Height);
            Rectangle rTop = new Rectangle(xTop, yTop, bmpTop.Width, bmpTop.Height);
            System.Diagnostics.Debug.WriteLine("Merge() \n\nrBg " + rBg.ToString() + "\nrTop " + rTop.ToString());
            if (Rectangle.Intersect(rBg, rTop) != rTop)
            {
                throw new ArgumentOutOfRangeException("Top BMP must be inside Bg one");
            }

            int   maxAlpha = 0;
            float bgAlpha  = 0;
            float topAlpha = 0;

            // Copy Color from background image into this (same as cloning bg image into 'this')
            ImageAdapter temp = new ImageAdapter((IImageAdapter)bmpBg);

            System.Diagnostics.Debug.WriteLine("Merge1() : Before the loop");
            for (int x = rBg.Left; x < rBg.Right; x++)
            {
                for (int y = rBg.Top; y < rBg.Bottom; y++)
                {
                    if (rTop.Contains(x, y))
                    {
                        IColor colorBg  = bmpBg[x - rBg.Left, y - rBg.Top];
                        IColor colorTop = bmpTop[x - rTop.Left, y - rTop.Top];
                        maxAlpha = Math.Max(colorBg.A, colorTop.A);
                        topAlpha = (float)colorTop.Alpha;
                        bgAlpha  = (float)((1f - colorTop.Alpha) * colorBg.Alpha);

                        IColor color = new ColorByte((byte)maxAlpha,
                                                     (byte)(bgAlpha * colorBg.R + topAlpha * colorTop.R),
                                                     (byte)(bgAlpha * colorBg.G + topAlpha * colorTop.G),
                                                     (byte)(bgAlpha * colorBg.B + topAlpha * colorTop.B));
                        temp[x - rBg.Left, y - rBg.Top] = color;
                    }
                }
            }
#if DEBUG
            ImageUtility.ToImageFile(temp, System.IO.Path.Combine(System.IO.Path.GetTempPath(), "After_Merge_This.png"));
#endif

            return((IImageAdapterUnmanaged)temp);
        }
Example #2
0
        private void InternalConstructor(Bitmap bmp)
        {
            if (bmp == null)
            {
                throw new ArgumentNullException("Bitmap passed in is null");
            }
            _colors = new IColor[bmp.Width, bmp.Height];

            _metadataInfo = new MetadataInfo(bmp.PropertyItems);


            //Verify that metadata correctly set the DPI
            //In the case where no dpi meta is stored with the image it defaults to the screen resolution
            //we fix that here in the metadata info
            Point metaDpi = MetadataInfoHelper.GetDpi(_metadataInfo);
            Point bmpDpi  = new Point((int)Math.Round(bmp.HorizontalResolution), (int)Math.Round(bmp.VerticalResolution));

            if (!metaDpi.Equals(bmpDpi))
            {
                MetadataInfoHelper.SetDpi(_metadataInfo, bmpDpi);
            }

            ImageUtility image = null;

            try
            {
                image = new ImageUtility(bmp); // Conversion to 32 bits done internally.
                image.GetSetPixelUnsafeBegin();
                byte[] BGRAStream = image.GetStreamBufferBGRA();
                image.GetSetPixelUnsafeRollBack();
                int size = BGRAStream.Length;
                for (int index = 0, x = 0, y = 0; index < size; index += 4, x++) // flat array to remove the cost of the computation (x + y *x)
                {
                    if (x >= Width)
                    {
                        x = 0; y++;
                    }
                    _colors[x, y] = new ColorByte(BGRAStream[index + 3], BGRAStream[index + 2], BGRAStream[index + 1], BGRAStream[index]);
                    if (_colors[x, y].ARGB == 0)
                    {
                        _colors[x, y].IsEmpty = true;
                    }
                }
                BGRAStream = null;
            }
            finally
            {
                if (image != null)
                {
                    image.Dispose(); image = null;
                }
                GC.Collect(GC.MaxGeneration);
            }
        }