Пример #1
0
        void UpdateImageSource()
        {
            int w = _bitmap.PixelWidth;
            int h = _bitmap.PixelHeight;

            var rt = _d2dContext;

            var bpTarget = new D2D.BitmapProperties1(
                new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied),
                (float)_bitmap.DpiX, (float)_bitmap.DpiY, D2D.BitmapOptions.Target | D2D.BitmapOptions.CannotDraw);

            var targetBmp = D2D.Bitmap1.Create(rt, new Size2L(w, h), bpTarget);

            rt.SetTarget(targetBmp);

            rt.BeginDraw();
            rt.Clear(null);

            var buffer = _bitmap.ToD2DBitmap1(rt, D2D.BitmapOptions.None);

            _warp.SetNormPositions(_warpStart, _warpEnd);
            _warp.Effect.SetInput(0, buffer);

            rt.DrawImage(_warp.Effect, Point2F.Empty);

            //_blur.SetInputEffect(0, _warp.Effect);
            //rt.DrawImage(_blur, Point2F.Empty);

            buffer.Dispose();

            if (!rt.EndDraw(true))
            {
                targetBmp.Dispose();
                DiscardDeviceResources();
                CreateDeviceResources();
                return;
            }
            rt.SetTarget(null);

            _bitmap.ImportAsFragment(targetBmp, rt, new RectL(w, h), 0, 0);

            targetBmp.Dispose();
        }
Пример #2
0
        void UpdateImageSource(ImageEffect imageEffect)
        {
            // some effects can change pixels outside the bounds of the source
            // image, so we need a margin to make those pixels visible
            var targetOffset = new Point2F(_marginLT, _marginLT);
            int w            = _bitmap.PixelWidth + _marginLT + _marginRB;
            int h            = _bitmap.PixelHeight + _marginLT + _marginRB;

            // the render target object
            var rt = _d2dContext;

            // create the target Direct2D bitmap
            var bpTarget = new D2D.BitmapProperties1(
                new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied),
                (float)_bitmap.DpiX, (float)_bitmap.DpiY, D2D.BitmapOptions.Target | D2D.BitmapOptions.CannotDraw);
            var targetBmp = D2D.Bitmap1.Create(rt, new Size2L(w, h), bpTarget);

            // associate the target bitmap with render target
            rt.SetTarget(targetBmp);

            // start drawing
            rt.BeginDraw();

            // clear the target bitmap
            rt.Clear(null);

            // convert C1Bitmap image to Direct2D image
            var d2dBitmap = _bitmap.ToD2DBitmap1(rt, D2D.BitmapOptions.None);

            // apply the effect or just draw the original image
            switch (imageEffect)
            {
            case ImageEffect.Original:
                rt.DrawImage(d2dBitmap, targetOffset);
                break;

            case ImageEffect.GaussianBlur:
                rt.DrawImage(ApplyGaussianBlur(d2dBitmap), targetOffset);
                break;

            case ImageEffect.Sharpen:
                rt.DrawImage(ApplySharpen(d2dBitmap), targetOffset);
                break;

            case ImageEffect.HorizontalSmear:
                rt.DrawImage(ApplyHorizontalSmear(d2dBitmap), targetOffset);
                break;

            case ImageEffect.Shadow:
                rt.DrawImage(ApplyShadow(d2dBitmap), targetOffset);
                break;

            case ImageEffect.DisplacementMap:
                rt.DrawImage(ApplyDisplacementMap(d2dBitmap), targetOffset);
                break;

            case ImageEffect.Emboss:
                rt.DrawImage(ApplyEmboss(d2dBitmap), targetOffset);
                break;

            case ImageEffect.EdgeDetect:
                rt.DrawImage(ApplyEdgeDetect(d2dBitmap), targetOffset);
                break;

            case ImageEffect.Sepia:
                rt.DrawImage(ApplySepia(d2dBitmap), targetOffset);
                break;
            }
            d2dBitmap.Dispose();

            // draw the text label in case of the Shadow effect
            if (imageEffect == ImageEffect.Shadow)
            {
                var mr = Matrix3x2.Rotation(-90f);
                var mt = Matrix3x2.Translation(targetOffset.X + 6f, targetOffset.Y + 344f);
                rt.Transform = mr * mt;
                _brush.SetColor(ColorF.White);
                rt.DrawTextLayout(new Point2F(-1f, -1f), _textLayout, _brush);
                _brush.SetColor(ColorF.DimGray);
                rt.DrawTextLayout(Point2F.Empty, _textLayout, _brush);
                rt.Transform = Matrix3x2.Identity;
            }

            // finish drawing (all drawing commands are executed at that moment)
            if (!rt.EndDraw(true))
            {
                targetBmp.Dispose();

                // try to recreate the device resources if the old GPU device was removed
                DiscardDeviceResources();
                CreateDeviceResources();
                return;
            }

            // detach the target bitmap
            rt.SetTarget(null);

            // create a temporary C1Bitmap object
            var outBitmap = new C1Bitmap(_bitmap.ImagingFactory);

            // import the image from Direct2D target bitmap to C1Bitmap
            outBitmap.Import(targetBmp, rt, new RectL(w, h));
            targetBmp.Dispose();

            // convert C1Bitmap to a System.Drawing.Bitmap
            ClearGdiBitmap();
            _lastGdiBitmap = outBitmap.ToGdiBitmap();
            outBitmap.Dispose();

            // show the result in the PictureBox
            pictureBox1.Image = _lastGdiBitmap;
        }
Пример #3
0
        void UpdateImageSource(bool applyWarpEffect)
        {
            Point2L surfaceOffset;

            DXGI.Surface dxgiSurface;

            int w  = _bitmap.PixelWidth;
            int h  = _bitmap.PixelHeight;
            var hr = _sisNative.BeginDraw(new RectL(w, h), out surfaceOffset, out dxgiSurface);

            if (hr == DXGI.ResultCode.DeviceRemoved || hr == DXGI.ResultCode.DeviceReset)
            {
                DiscardDeviceResources();
                CreateDeviceResources();
                _sisNative.SetDevice(_dxgiDevice);
                return;
            }
            hr.CheckError();

            var rt = _d2dContext;

            var bpTarget = new D2D.BitmapProperties1(
                new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied),
                (float)_bitmap.DpiX, (float)_bitmap.DpiY, D2D.BitmapOptions.Target | D2D.BitmapOptions.CannotDraw);

            var targetBmp = D2D.Bitmap1.Create(rt, dxgiSurface, bpTarget);

            dxgiSurface.Dispose();

            rt.SetTarget(targetBmp);

            rt.BeginDraw();
            rt.Clear(null);

            var buffer = _bitmap.ToD2DBitmap1(rt, D2D.BitmapOptions.None);

            if (!applyWarpEffect)
            {
                rt.DrawBitmap(buffer, new RectF(surfaceOffset.X, surfaceOffset.Y, w, h));
            }
            else
            {
                _warp.SetNormPositions(_warpStart, _warpEnd);
                _warp.Effect.SetInput(0, buffer);

                rt.DrawImage(_warp.Effect, new Point2F(surfaceOffset.X, surfaceOffset.Y));

                //_blur.SetInputEffect(0, _warp.Effect);
                //rt.DrawImage(_blur, new Point2F(surfaceOffset.X, surfaceOffset.Y));
            }
            buffer.Dispose();

            rt.EndDraw();
            rt.SetTarget(null);

            if (applyWarpEffect)
            {
                var srcRect = new RectL(surfaceOffset.X, surfaceOffset.Y, w, h);
                _bitmap.ImportAsFragment(targetBmp, rt, srcRect, 0, 0);
            }
            targetBmp.Dispose();

            _sisNative.EndDraw();
        }
Пример #4
0
        /// <summary>
        /// Draws the image on SurfaceImageSource.
        /// </summary>
        void UpdateImageSource(ImageEffect imageEffect)
        {
            int     w             = _bitmap.PixelWidth + _marginLT + _marginRB;
            int     h             = _bitmap.PixelHeight + _marginLT + _marginRB;
            Point2L surfaceOffset = Point2L.Empty;

            DXGI.Surface dxgiSurface = null;
            var          hr          = HResult.Ok;

            // receive the target DXGI.Surface and offset for drawing
            for (int i = 0; i <= 1; i++)
            {
                hr = _sisNative.BeginDraw(new RectL(w, h), out surfaceOffset, out dxgiSurface);
                if ((hr != DXGI.ResultCode.DeviceRemoved && hr != DXGI.ResultCode.DeviceReset) || i > 0)
                {
                    break;
                }

                // try to recreate the device resources if the old GPU device was removed
                DiscardDeviceResources();
                CreateDeviceResources();
                _sisNative.SetDevice(_dxgiDevice);
            }
            hr.CheckError();

            // the render target object
            var rt = _d2dContext;

            // create the target Direct2D bitmap for the given DXGI.Surface
            var bpTarget = new D2D.BitmapProperties1(
                new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied),
                (float)_bitmap.DpiX, (float)_bitmap.DpiY, D2D.BitmapOptions.Target | D2D.BitmapOptions.CannotDraw);

            var targetBmp = D2D.Bitmap1.Create(rt, dxgiSurface, bpTarget);

            dxgiSurface.Dispose();

            // associate the target bitmap with render target
            rt.SetTarget(targetBmp);
            targetBmp.Dispose();

            // start drawing
            rt.BeginDraw();

            // clear the target bitmap
            rt.Clear(null);

            // convert C1Bitmap image to Direct2D image
            var d2dBitmap = _bitmap.ToD2DBitmap1(rt, D2D.BitmapOptions.None);

            // apply the effect or just draw the original image
            surfaceOffset.X += _marginLT;
            surfaceOffset.Y += _marginLT;
            var targetOffset = surfaceOffset.ToPoint2F();

            switch (imageEffect)
            {
            case ImageEffect.Original:
                rt.DrawImage(d2dBitmap, targetOffset);
                break;

            case ImageEffect.GaussianBlur:
                rt.DrawImage(ApplyGaussianBlur(d2dBitmap), targetOffset);
                break;

            case ImageEffect.Sharpen:
                rt.DrawImage(ApplySharpen(d2dBitmap), targetOffset);
                break;

            case ImageEffect.HorizontalSmear:
                rt.DrawImage(ApplyHorizontalSmear(d2dBitmap), targetOffset);
                break;

            case ImageEffect.Shadow:
                rt.DrawImage(ApplyShadow(d2dBitmap), targetOffset);
                break;

            case ImageEffect.DisplacementMap:
                rt.DrawImage(ApplyDisplacementMap(d2dBitmap), targetOffset);
                break;

            case ImageEffect.Emboss:
                rt.DrawImage(ApplyEmboss(d2dBitmap), targetOffset);
                break;

            case ImageEffect.EdgeDetect:
                rt.DrawImage(ApplyEdgeDetect(d2dBitmap), targetOffset);
                break;

            case ImageEffect.Sepia:
                rt.DrawImage(ApplySepia(d2dBitmap), targetOffset);
                break;
            }
            d2dBitmap.Dispose();

            // draw the additional text label in case of the Shadow effect
            if (imageEffect == ImageEffect.Shadow)
            {
                var mr = Matrix3x2.Rotation(-90f);
                var mt = Matrix3x2.Translation(targetOffset.X + 6f, targetOffset.Y + 344f);
                rt.Transform = mr * mt;
                _brush.SetColor(ColorF.White);
                rt.DrawTextLayout(new Point2F(-1f, -1f), _textLayout, _brush);
                _brush.SetColor(ColorF.DimGray);
                rt.DrawTextLayout(Point2F.Empty, _textLayout, _brush);
                rt.Transform = Matrix3x2.Identity;
            }

            // finish drawing (all drawing commands are executed at that moment)
            rt.EndDraw();

            // detach and actually dispose the target bitmap
            rt.SetTarget(null);

            // complete drawing on SurfaceImageSource
            _sisNative.EndDraw();
        }
        void Render(IntPtr hdc)
        {
            #region prepare device resources

            var rt = _d2dContext;
            if (rt == null)
            {
                CreateDeviceResources();
                rt = _d2dContext;
            }

            #endregion

            #region draw to the intermediate bitmap (of the original bitmap size)

            if (_imBmp == null && _bitmap.HasImage)
            {
                var bmProps = new D2D.BitmapProperties1(
                    new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied),
                    (float)_bitmap.DpiX, (float)_bitmap.DpiY, D2D.BitmapOptions.Target);
                _imBmp        = D2D.Bitmap1.Create(rt, new Size2L(_bitmap.PixelWidth, _bitmap.PixelHeight), bmProps);
                _needUpdateIM = true;
            }
            if (_needUpdateIM && _imBmp != null)
            {
                _needUpdateIM = false;

                rt.SetTarget(_imBmp);
                rt.BeginDraw();

                rt.Clear(null);

                var buffer = _bitmap.ToD2DBitmap1(rt, D2D.BitmapOptions.None);
                if (!_applyEffect)
                {
                    rt.DrawImage(buffer);
                }
                else
                {
                    _warp.SetNormPositions(_warpEnd, _warpStart);
                    _warp.Effect.SetInput(0, buffer);

                    rt.DrawImage(_warp.Effect, Point2F.Empty);

                    //_blur.SetInputEffect(0, _warp.Effect);
                    //rt.DrawImage(_blur, Point2F.Empty);
                }
                buffer.Dispose();

                if (!rt.EndDraw(true))
                {
                    DiscardDeviceResources();
                    return;
                }
                rt.SetTarget(null);

                if (_applyEffect)
                {
                    _bitmap.ImportAsFragment(_imBmp, rt, new RectL(_bitmap.PixelWidth, _bitmap.PixelHeight), 0, 0);
                    _applyEffect = false;
                }
            }

            #endregion

            #region draw the result to the target bitmap (of the target control size)

            if (_targetBmp == null)
            {
                var bmProps = new D2D.BitmapProperties1(
                    new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Ignore),
                    _dpiX, _dpiY, D2D.BitmapOptions.Target | D2D.BitmapOptions.GdiCompatible);
                _targetBmp = D2D.Bitmap1.Create(rt, new Size2L(Width, Height), bmProps);
            }
            rt.SetTarget(_targetBmp);

            rt.BeginDraw();
            rt.Clear(new ColorF(this.BackColor));

            if (!_targetRect.IsEmpty)
            {
                if (_imBmp != null)
                {
                    rt.DrawBitmap(_imBmp, _targetRect);
                }

                if (_drawLine)
                {
                    var pt1 = new Point2F(_targetRect.Width * _warpStart.X + _targetRect.Left, _targetRect.Height * _warpStart.Y + _targetRect.Top);
                    var pt2 = new Point2F(_targetRect.Width * _warpEnd.X + _targetRect.Left, _targetRect.Height * _warpEnd.Y + _targetRect.Top);
                    rt.DrawLine(pt1, pt2, _lineBrush, _scaleFactor * 7, _lineStrokeStyle);
                }
            }

            #endregion

            #region BitBlt to GDI

            var gi   = rt.QueryGdiInterop();
            var gidc = gi.GetDC(D2D.DeviceContextInitializeMode.Copy);
            Win32.BitBlt(hdc, 0, 0, Width, Height, gidc, 0, 0, Win32.SRCCOPY);
            gi.ReleaseDC(null);
            gi.Dispose();

            #endregion

            #region EndDraw

            if (!rt.EndDraw(true))
            {
                DiscardDeviceResources();
                return;
            }
            rt.SetTarget(null);

            #endregion
        }