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(); }
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; }
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(); }
/// <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 }