How to set up a SwapChain1 for 2D rendering in SharpDX? - c#

So I've been using SharpDX, a C# DirectX wrapper to program in Direct3D11 and Direct2D, to draw to a RenderForm window in my program. However the SwapChain.Present information states I should use a SwapChain1.Present1 instead and I cannot figure out how to change my code to work with SwapChain1. The CreateWithSwapChain method in Device and even Device1 only works with a normal SwapChain and I don't know how else to simply setup this up.
These are the namespaces being used.
using SharpDX.Direct2D1;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Windows;
using Device = SharpDX.Direct3D11.Device;
using Factory = SharpDX.Direct2D1.Factory;
using Resource = SharpDX.Direct3D11.Resource;
And this is the code I'm using to setup the RenderTarget.
SwapChainDescription desc = new SwapChainDescription() {
BufferCount = 1,
ModeDescription = new ModeDescription(
DXWindow.GetWindow().ClientSize.Width,
DXWindow.GetWindow().ClientSize.Height,
new Rational(60, 1),
Format.R8G8B8A8_UNorm),
IsWindowed = true,
OutputHandle = DXWindow.GetWindow().Handle,
SampleDescription = new SampleDescription(1, 0),
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput
};
Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.BgraSupport, new SharpDX.Direct3D.FeatureLevel[] { SharpDX.Direct3D.FeatureLevel.Level_10_0 }, desc, out Device device, out swapchain);
Texture2D backbuffer = Resource.FromSwapChain<Texture2D>(swapchain, 0);
RenderTargetView renderview = new RenderTargetView(device, backbuffer);
renderView = new RenderTarget(new Factory(), backbuffer.QueryInterface<Surface>(), new RenderTargetProperties(new PixelFormat(Format.Unknown, SharpDX.Direct2D1.AlphaMode.Premultiplied)));
RenderLoop.Run(DXWindow.GetWindow(), CoreLoop);
DXWindow.GetWindow() get returns a RenderForm and CoreLoop is the render loop where I make Draw calls and Present. How do I use SwapChain1 instead of SwapChain in this?

I've posted my code that works for Swapchain2. You can interchange the queryinterface with SwapChain1 where needed. I've included code for Windows Forms and UWP initialisation. I am not sure which one you are doing here. So the #define allows you to swap, although I havent done much more work on UWP and it may of been broken since I last touched it.
// Function Create()
DXGI.Device1 dxgiDevice1_ = _d3dDevice.QueryInterface<DXGI.Device1>();
DXGI.Adapter dxgiAdapter_ = dxgiDevice1_.Adapter;
DXGI.Factory2 dxgiFactory2_ = dxgiAdapter_.GetParent<DXGI.Factory2>();
ReleaseAllDeviceContexts(true);
if (_swapChain != null)
{
_swapChain.Dispose();
}
if (_swapChainBuffer != null)
{
_swapChainBuffer.Dispose();
}
if (_parentSwapchain != null)
{
_parentSwapchain.Dispose();
}
#if !WINDOWS_UWP
DXGI.SwapChainDescription1 swapChainDescription_ = new DXGI.SwapChainDescription1()
{
AlphaMode = DXGI.AlphaMode.Ignore,
Width = _modeDescription.Width,
Height = _modeDescription.Height,
Format = DXGI.Format.R8G8B8A8_UNorm,
Scaling = DXGI.Scaling.None,
BufferCount = _swapChainBufferCount,
SwapEffect = SharpDX.DXGI.SwapEffect.FlipDiscard,
Flags = SharpDX.DXGI.SwapChainFlags.AllowModeSwitch,
Usage = DXGI.Usage.BackBuffer | DXGI.Usage.RenderTargetOutput,
SampleDescription = new DXGI.SampleDescription() { Count = 1, Quality = 0 },
Stereo = false,
};
_parentSwapchain1 = new DXGI.SwapChain1(dxgiFactory2_, _d3dDevice, _parentContainer.WindowHandle, ref swapChainDescription_, new DXGI.SwapChainFullScreenDescription()
{
RefreshRate = _modeDescription.RefreshRate,
Scaling = SharpDX.DXGI.DisplayModeScaling.Unspecified,
Windowed = isFullscreen == false,
ScanlineOrdering = DXGI.DisplayModeScanlineOrder.Unspecified,
}
);
_swapChain = _parentSwapchain.QueryInterface<DXGI.SwapChain2>();
#else
DXGI.SwapChainDescription1 swapChainDescription = new DXGI.SwapChainDescription1()
{
AlphaMode = DXGI.AlphaMode.Ignore,
Width = _modeDescription.Width,
Height = _modeDescription.Height,
Format = DXGI.Format.R8G8B8A8_UNorm,
Scaling = DXGI.Scaling.Stretch,
BufferCount = _swapChainBufferCount,
SwapEffect = SharpDX.DXGI.SwapEffect.FlipDiscard,
Flags = SharpDX.DXGI.SwapChainFlags.AllowModeSwitch | DXGI.SwapChainFlags.AllowTearing,
Usage = DXGI.Usage.BackBuffer | DXGI.Usage.RenderTargetOutput,
SampleDescription = new DXGI.SampleDescription() { Count = 1, Quality = 0 },
Stereo = false,
};
ComObject obj = new ComObject(_parentContainer.WindowHandle);
_parentSwapchain1 = new DXGI.SwapChain1(dxgiFactory3, _device, ref swapChainDescription, null);
_swapChain2 = _parentSwapchain1.QueryInterface<DXGI.SwapChain2>();
using (DXGI.ISwapChainPanelNative nativeObject = ComObject.As<DXGI.ISwapChainPanelNative>(_parentContainer.WindowHandle))
{
// Set its swap chain.
nativeObject.SwapChain = _swapChain2;
}
#endif
_swapChainBuffer = D3D11.Texture2D.FromSwapChain<D3D11.Texture2D>(_swapChain, 0);
dxgiDevice1_.Dispose();
dxgiAdapter_.Dispose();
dxgiFactory2_.Dispose();
The resize of the buffer is also included in here for reference as well. Ignore some of the custom code though, its all internal my game, so some of this wont make sense.
public void ResizeBuffers(bool isFullscreen)
{
try
{
if (_swapChainBuffer != null)
{
// if (_parentSwapchain1.IsFullScreen != isFullscreen)
{
ReleaseAllDeviceContexts(true);
SharpDX.Utilities.Dispose(ref _swapChain2);
SharpDX.Utilities.Dispose(ref _swapChainBuffer);
#if !WINDOWS_UWP
_parentSwapchain1.IsFullScreen = isFullscreen;
_parentSwapchain1.ResizeBuffers(0, _modeDescription.Width, _modeDescription.Height, DXGI.Format.Unknown, SharpDX.DXGI.SwapChainFlags.AllowModeSwitch);
if (isFullscreen)
{
_parentSwapchain1.ResizeTarget(ref _modeDescription);
}
#else
_parentSwapchain1.ResizeBuffers(0, _modeDescription.Width, _modeDescription.Height, DXGI.Format.Unknown, DXGI.SwapChainFlags.AllowTearing);
#endif
_swapChain2 = _parentSwapchain1.QueryInterface<DXGI.SwapChain2>();
_swapChainBuffer = D3D11.Texture2D.FromSwapChain<D3D11.Texture2D>(_swapChain2, 0);
}
_renderViewport = new Viewport(0, 0, _modeDescription.Width, _modeDescription.Height);
_d3dDevice.ImmediateContext1.Rasterizer.SetViewport(_renderViewport);
}
}
catch (Exception ex)
{
ErrorHandler.DoErrorHandling(ex, ErrorHandler.GetCurrentMethod(ex));
}
}

Related

How to disable animations on Highcharts Dotnet C# MVC?

So I have begun using Dotnet.Highcharts in Visual Studio with C# and MVC,
Its quite different from its javascript counterpart, I need to use ghostjs to take a picture from my web page to send as a report, as many must know, this means that animations interfere with this working properly as bars show up to half of the height they should be.
I'm using the recommended coding from Dotnet.highcharts which mostly uses Razor to configure the chart.
I have tried disabling animations in all these places:
PlotOptions = new PlotOptions
{
Column = new PlotOptionsColumn
{
PointPadding = 0.2,
BorderWidth = 0,
Animation = new Animation() { Enabled = false, Duration = 0 }
},
Series = new PlotOptionsSeries
{
Animation = new Animation() { Enabled = false, Duration = 0}
}
},
chartOptions.Drilldown.Animation = new Animation() { Enabled = false, Duration = 0};
chartOptions.Chart.Animation.Enabled = false;
and still the chart keeps animating, I just don't know what is going on
here is my full Razor code for the chart
var chartOptions = new Highcharts
{
Title = new Title { Text = "Transactions" },
Subtitle = new Subtitle { Text = "December" },
XAxis = new List<XAxis>
{
new XAxis
{
Categories = ViewBag.ListCategories
}
},
YAxis = new List<YAxis>
{
new YAxis
{
Min = 0,
Title = new YAxisTitle
{
Text = "Tx"
}
}
},
Tooltip = new Tooltip
{
HeaderFormat = "<span style='font-size:10px'>{point.key}</span><table style='font-size:12px'>",
PointFormat = "<tr><td style='color:{series.color};padding:0'>{series.name}: </td><td style='padding:0'><b>{point.y:.0f}</b></td></tr>",
FooterFormat = "</table>",
Shared = true,
UseHTML = true
},
PlotOptions = new PlotOptions
{
Column = new PlotOptionsColumn
{
PointPadding = 0.2,
BorderWidth = 0,
Animation = new Animation() { Enabled = false, Duration = 0 }
},
Series = new PlotOptionsSeries
{
Animation = new Animation() { Enabled = false, Duration = 0}
}
},
Series = new List<Series>
{
new ColumnSeries
{
Name = "TX",
Data = ViewData["DataTX"] as List<ColumnSeriesData>
}
}
};
chartOptions.ID = "chart";
chartOptions.Drilldown.Animation = new Animation() { Enabled = false, Duration = 0};
chartOptions.Chart.Animation.Enabled = false;
var renderer = new HighchartsRenderer(chartOptions);
This one worked for me. Had to play with it a while, seems there's no clear documentation.
DotNet.Highcharts.Highcharts chart = new DotNet.Highcharts.Highcharts("chart")
.InitChart(new Chart { DefaultSeriesType = ChartTypes.Areaspline})
.SetTitle(new Title
{
Text = "myLabel",
X = -20
})
.SetSeries(new[]
{
new Series { Name = "MyUsers", Data = new Data(myData), PlotOptionsSeries=new PlotOptionsSeries(){Animation=new Animation(false)} }
});
I found a way to disable the animation inside highcharts.js (From another question for the js version)
showCheckbox: !1,
animation: { duration: 1E3 }
, events: {},
I changed 1E3 to 0 and it worked, however, this is not the optimal solution, there must be a way to achieve this the right way. The whole point of the highcharts dll for visual studio is the ability to use highcharts without touching javascript
For now, I won't accept my own answer as the answer

MvvmCross iOS hamburger Menu without plugins iOS Native

Okay,This is What I would like to do in MvvmCross without any plugins just native code. I did find a Tutorial on how to it, but I would like it in MvvmCross.iOS Have a look at what I would like to do in MvvmCross.iOS
Please advise or forward a better tutorial for MvvmCross.iOS
points to remember
The hamburger menu should have a draggable effect like the image I have linked
what I have tried
ViewDidLoad() -->
UIPanGestureRecognizer gesture = new UIPanGestureRecognizer();
gesture.AddTarget(() => HandleDrag(gesture));
this.View.AddGestureRecognizer(gesture);
panGestureRecognizer = new UIScreenEdgePanGestureRecognizer ( HandleSwipeRight);
panGestureRecognizer.Edges = UIRectEdge.Left;
this.View.AddGestureRecognizer(panGestureRecognizer);
HandleDrag() -->
protected void HandleDrag(UIPanGestureRecognizer recognizer)
{
PointF offset2 = (System.Drawing.PointF)recognizer.TranslationInView(View);
if (recognizer.State != (UIGestureRecognizerState.Cancelled | UIGestureRecognizerState.Failed
| UIGestureRecognizerState.Possible))
{
Console.WriteLine("Here");
// NEED TO LOAD ANOTHER VIEW HERE
openMenu();
}
}
openMenu() -->
public void openMenu()
{
viewBlack.Hidden = false;
this.view.Hidden = false;
UIView.Animate(
duration: 0.3,
delay: 0,
options: UIViewAnimationOptions.CurveEaseInOut |
UIViewAnimationOptions.Autoreverse,
animation: () =>
{
this.view.LayoutIfNeeded();
this.viewBlack.Alpha = this.maxBlackViewAlpha = 0.5f;
},
completion: () =>
{
panGestureRecognizer.Enabled = false;
}
);
}
hideMenu() -->
public void closeMenu(){
UIView.Animate(
duration: 0.3,
delay: 0,
options: UIViewAnimationOptions.CurveEaseInOut |
UIViewAnimationOptions.Autoreverse,
animation: () =>
{
this.view.LayoutIfNeeded();
this.viewBlack.Alpha = 0;
},
completion: () =>
{
panGestureRecognizer.Enabled = true;
viewBlack.Hidden = true;
view.Hidden = true;
}
);
}
My Custom Hamburger menu UIView -->
view = new UIView();
view.Frame = new CGRect(0, 0, UIScreen.MainScreen.Bounds.Width / 1.1, UIScreen.MainScreen.Bounds.Height);
var gradientLayer = new CAGradientLayer();
gradientLayer.Colors = new[] { UIColor.FromRGB(64, 0, 128).CGColor, UIColor.FromRGB(0, 0, 128).CGColor };
gradientLayer.Locations = new NSNumber[] { 0, 1 };
gradientLayer.Frame = view.Frame;
view.BackgroundColor = UIColor.Clear;
view.Layer.AddSublayer(gradientLayer);
var viewline = new UIView();
viewline.Frame = new CGRect(20, 60, 100, 1);
viewline.BackgroundColor = UIColor.White;
var bb = new UIBarButtonItem();
var Allbutton = new UIButton(new CGRect(0, 20, 135, 20));
Allbutton.SetTitleColor(UIColor.Black, UIControlState.Normal);
Allbutton.TitleLabel.BackgroundColor = UIColor.White;
Allbutton.SetTitle("Login", UIControlState.Normal);
var myPrefbutton = new UIButton(new CGRect(0, 120, 135, 20));
myPrefbutton.SetTitleColor(UIColor.Black, UIControlState.Normal);
myPrefbutton.SetTitle("Logout", UIControlState.Normal);
myPrefbutton.TitleLabel.BackgroundColor = UIColor.White;
view.BackgroundColor = UIColor.White;
view.Add(Allbutton);
view.Add(viewline);
view.Add(myPrefbutton);
view.Hidden = true;
this.View.AddSubviews(view);
this is the only code I was able to convert into MvvmCross.iOS from tutorial(SWIFT) and it's works but
I cannot drag the menu to show, what happens is that it load up normally and it's fast
Note!!! I am not using any Storyboards or nib files just using pure code for this hamburger menu
please has a good look at the .gif notice that the menu is draggable which makes it's animation slow and not fast.
if I have confused you please don't be sad I have just started coding in iOS and MvvmCross... I'm still a noob
Got it to work
first had to create a UIVew class -->
SideMenuView : MvxViewController
then set the X to minus... it will be zero if a user selects the navbaritem I also added a overlay UIView
viewBlack = new UIView();
viewBlack.Frame = new CGRect(0, 0, UIScreen.MainScreen.Bounds.Width, UIScreen.MainScreen.Bounds.Height);
viewBlack.BackgroundColor = UIColor.Black;
viewBlack.Alpha = 0.5f;
viewBlack.Hidden = true;
this.View.AddSubviews(viewBlack);

How can an animation be added properly to a CALayer when using AVAssetExportSession in Xamarin.ios?

I need your help regarding an animation I want to apply to an overlay image I add to a mp4 video. To add an overlay on a video, I followed Ray Wenderlich tutorials here: https://www.raywenderlich.com/30200/avfoundation-tutorial-adding-overlays-and-animations-to-videos. At the end of that link, an animation is created on an overlay.
Ray Wenderlich is not coding with c# but I do since I use Xamarin to create my app.
Using the animation, the overlay is supposed to fade away during the very first seconds of the video. But nothing happens. I mean nothing animated happens except for the video: the overlay is well put on top of the video but it does not fade away.
Most of the posts I read about animations and CALayer create an animation within a UIView.
So I am asking myself: is the animation not working because I use c# or did I write something wrong?
Can somebody help me with this, please?
This is the function I wrote:
public static void addFadeOverlayAtTheBeginning (NSUrl source, String overlay, long secondsToFade, NSUrl destination)
{
AVUrlAsset videoAsset = new AVUrlAsset(source);
if (secondsToFade > videoAsset.Duration.Seconds)
secondsToFade = (long)videoAsset.Duration.Seconds;
CALayer overlayLayer = CALayer.Create();
UIImage image = new UIImage(overlay);
image.CreateResizableImage(new UIEdgeInsets(0, 0, videoAsset.NaturalSize.Width, videoAsset.NaturalSize.Height));
overlayLayer.Contents = image.CGImage;
overlayLayer.Frame = new CGRect(0, 0, videoAsset.NaturalSize.Width, videoAsset.NaturalSize.Height);
overlayLayer.MasksToBounds = true;
CABasicAnimation animation = CABasicAnimation.FromKeyPath(#"opacity");
animation.BeginTime = 0; // GetSeconds(image.CGImage.StartTime);
animation.Duration = secondsToFade;
animation.SetFrom (NSNumber.FromFloat (1));
animation.SetTo (NSNumber.FromFloat(0));
overlayLayer.AddAnimation(animation, #"opacity");
AVMutableComposition videoComposition = AVMutableComposition.Create();
AVMutableCompositionTrack track = videoComposition.AddMutableTrack(AVMediaType.Video, 0);
AVAssetTrack sourceVideoTrack = videoAsset.TracksWithMediaType(AVMediaType.Video)[0];
CMTimeRange timeRangeInAsset = new CMTimeRange();
timeRangeInAsset.Start = CMTime.Zero;
timeRangeInAsset.Duration = videoAsset.Duration;
NSError videoInsertError = null;
track.InsertTimeRange(timeRangeInAsset, sourceVideoTrack, CMTime.Zero, out videoInsertError);
track.PreferredTransform = sourceVideoTrack.PreferredTransform;
CALayer parentLayer = CALayer.Create();
CALayer videoLayer = CALayer.Create();
parentLayer.Frame = new CGRect(0, 0, videoAsset.NaturalSize.Width, videoAsset.NaturalSize.Height);
videoLayer.Frame = new CGRect(0, 0, videoAsset.NaturalSize.Width, videoAsset.NaturalSize.Height);
parentLayer.AddSublayer(videoLayer);
parentLayer.AddSublayer(overlayLayer);
//parentLayer.AddAnimation(animation, "opacity");
AVMutableVideoComposition animationComposition = AVMutableVideoComposition.Create(); //videoComposition
animationComposition.AnimationTool = AVVideoCompositionCoreAnimationTool.FromLayer(videoLayer, parentLayer);
animationComposition.RenderSize = videoAsset.NaturalSize;
animationComposition.FrameDuration = new CMTime(1, 30);
AVMutableVideoCompositionInstruction instruction = AVMutableVideoCompositionInstruction.Create() as AVMutableVideoCompositionInstruction;
CMTimeRange timeRangeInstruction = new CMTimeRange();
timeRangeInstruction.Start = CMTime.Zero;
timeRangeInstruction.Duration = videoComposition.Duration;
instruction.TimeRange = timeRangeInstruction;
AVMutableVideoCompositionLayerInstruction layerInstruction = AVMutableVideoCompositionLayerInstruction.FromAssetTrack(track);
CMTimeRange timeRangeFading = new CMTimeRange();
timeRangeFading.Start = CMTime.Zero;
timeRangeFading.Duration = new CMTime(secondsToFade, 1);
//layerInstruction.SetOpacityRamp(1, 0, timeRangeFading);
instruction.LayerInstructions = new AVVideoCompositionLayerInstruction[] { layerInstruction };
List<AVVideoCompositionInstruction> instructions = new List<AVVideoCompositionInstruction>();
instructions.Add(instruction);
animationComposition.Instructions = instructions.ToArray();
if (File.Exists(destination.Path))
File.Delete(destination.Path);
AVAssetExportSession exporter = new AVAssetExportSession(videoComposition, AVAssetExportSession.PresetHighestQuality);
exporter.OutputUrl = destination;
exporter.VideoComposition = animationComposition;
exporter.OutputFileType = AVFileType.Mpeg4;
exporter.ExportAsynchronously(() => {
VideoManagement.state ++;
AVAssetExportSessionStatus status = exporter.Status;
Console.WriteLine("addFadeOverlayAtTheBeginning Done. Status: " + status.ToString());
switch (status)
{
case AVAssetExportSessionStatus.Completed:
Console.WriteLine("Sucessfully Completed");
if (File.Exists(destination.Path))
{
Console.WriteLine(String.Format("Saved to {0}", destination.Path));
}
else
Console.WriteLine("Failed");
break;
case AVAssetExportSessionStatus.Cancelled:
break;
case AVAssetExportSessionStatus.Exporting:
break;
case AVAssetExportSessionStatus.Failed:
Console.WriteLine("Task failed => {0}", exporter.Error);
Console.WriteLine(exporter.Error.Description);
break;
case AVAssetExportSessionStatus.Unknown:
break;
case AVAssetExportSessionStatus.Waiting:
break;
default:
break;
}
});
}
OK. Found it.
Apparently, animation.BeginTime = 0; is not supported. I changed it to 0.01 and everything works fine.
double Epsilon = 0.01;
if (secondsToFade > videoAsset.Duration.Seconds - Epsilon)
secondsToFade = videoAsset.Duration.Seconds - Epsilon;
CALayer overlayLayer = CALayer.Create();
UIImage image = new UIImage(overlay);
image.CreateResizableImage(new UIEdgeInsets(0, 0, videoAsset.NaturalSize.Width, videoAsset.NaturalSize.Height));
overlayLayer.Contents = image.CGImage;
overlayLayer.Frame = new CGRect(0, 0, videoAsset.NaturalSize.Width, videoAsset.NaturalSize.Height);
overlayLayer.MasksToBounds = true;
//On crée l'animation pour le CAlayer
CABasicAnimation animation = CABasicAnimation.FromKeyPath(#"opacity");
animation.BeginTime = Epsilon;
animation.Duration = secondsToFade;
animation.SetFrom (NSNumber.FromFloat (1));
animation.SetTo (NSNumber.FromFloat(0));
animation.FillMode = CAFillMode.Forwards;
animation.RemovedOnCompletion = false;

SharpDX 3 loading .DDS to apply onto a 3d model (C#)

I'm attempting to create a model viewer for a game to try and learn SharpDX but the game uses .DDS files and the viewer can only read .BMPs. I've looked far and wide on the webs and the only things I can find are load them but don't seem to work for SharpDX (I don't know im a noob :D)
using SharpDX.Direct3D11;
using SharpDX.WIC;
namespace ModelViewer.Programming.GraphicClasses
{
public class TextureClass
{
public ShaderResourceView TextureResource { get; private set; }
public bool Init(Device device, string fileName)
{
try
{
using (var texture = LoadFromFile(device, new ImagingFactory(), fileName))
{
ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription()
{
Format = texture.Description.Format,
Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D,
};
srvDesc.Texture2D.MostDetailedMip = 0;
srvDesc.Texture2D.MipLevels = -1;
TextureResource = new ShaderResourceView(device, texture, srvDesc);
device.ImmediateContext.GenerateMips(TextureResource);
}
return true;
}
catch
{
return false;
}
}
public void Shutdown()
{
TextureResource?.Dispose();
TextureResource = null;
}
public Texture2D LoadFromFile(Device device, ImagingFactory factory, string fileName)
{
using (var bs = LoadBitmap(factory, fileName))
return CreateTextureFromBitmap(device, bs);
}
public BitmapSource LoadBitmap(ImagingFactory factory, string filename)
{
var bitmapDecoder = new BitmapDecoder(factory, filename, DecodeOptions.CacheOnDemand);
var result = new FormatConverter(factory);
result.Initialize(bitmapDecoder.GetFrame(0), SharpDX.WIC.PixelFormat.Format32bppPRGBA, BitmapDitherType.None, null, 0.0, BitmapPaletteType.Custom);
return result;
}
public Texture2D CreateTextureFromBitmap(Device device, BitmapSource bitmapSource)
{
int stride = bitmapSource.Size.Width * 4;
using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true))
{
bitmapSource.CopyPixels(stride, buffer);
return new Texture2D(device, new Texture2DDescription()
{
Width = bitmapSource.Size.Width,
Height = bitmapSource.Size.Height,
ArraySize = 1,
BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget,
Usage = ResourceUsage.Default,
CpuAccessFlags = CpuAccessFlags.None,
Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
MipLevels = 1,
OptionFlags = ResourceOptionFlags.GenerateMipMaps,
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
},
new SharpDX.DataRectangle(buffer.DataPointer, stride));
}
}
}
}
I have a feeling this will need to be completely redone to utilize the DDS format. Is it easier to simply read one and then convert it to a bitmap?

How can I return the image?

It is created by a coordinate system with the two codesnippets listed below. Unfortunately, the second code snippet saves the image to the desktop. I would like to have the "image" returned. How can I return the image of the coordinate system? ( I have a method which has a return value as a picture )
At the end it should be preview = image;
So that from the coordinate system an "image" and not to the desktop is stored, but I can return it.
var stream = new MemoryStream();
var pngExporter = new PngExporter { Width = 600, Height = 400, Background = OxyColors.White };
pngExporter.Export(plotModel, stream);
preview = stream; //Does not work unfortunately
var pngExporter = new PngExporter { Width = 350, Height = 350, Background = OxyColors.White };
pngExporter.ExportToFile(plotModel, #"C:\Users\user\Desktop\test.png");
public bool createPreview(out string errorMessage, out System.Drawing.Image preview, int pWidth, int pHeight, int pMargin)
{
errorMessage = null;
preview = null;
bool folded = false;
try
{
PlotModel plotModel = new PlotModel { Title = "Vorschaukomponente" };
plotModel.Axes.Add(new OxyPlot.Axes.LinearAxis { Position = OxyPlot.Axes.AxisPosition.Bottom, MinimumPadding = 0.1, MaximumPadding = 0.1 });
plotModel.Axes.Add(new OxyPlot.Axes.LinearAxis { Position = OxyPlot.Axes.AxisPosition.Left, MinimumPadding = 0.1, MaximumPadding = 0.1 });
var series1 = new OxyPlot.Series.LineSeries
{
LineStyle = LineStyle.None,
MarkerType = MarkerType.Circle,
MarkerSize = 2,
MarkerFill = OxyColors.Transparent,
MarkerStroke = OxyColors.Black,
MarkerStrokeThickness = 1
};
if (pointX.Count == pointY.Count)
{
for (int i = 0; i < pointX.Count; i++)
{
for (int g = i; g < pointY.Count; g++)
{
series1.Points.Add(new DataPoint(pointX[i], pointY[g]));
Console.WriteLine(i+1 + " | "+ pointX[i].ToString() + "/" + pointY[g]);
break;
}
}
series1.Smooth = true;
plotModel.Series.Add(series1);
try
{
var stream = new MemoryStream();
var pngExporter = new PngExporter { Width = 600, Height = 400, Background = OxyColors.White };
pngExporter.Export(plotModel, stream);
preview = stream;
// var pngExporter = new PngExporter { Width = 350, Height = 350, Background = OxyColors.White };
// pngExporter.ExportToFile(plotModel, #"C:\Users\user\Desktop\test.png");
folded = true;
}
catch (Exception exc)
{
System.Diagnostics.Debug.WriteLine(exc.Message);
errorMessage = "Es konnt kein Bild erstellt werden.";
folded = false;
}
}
else
{
errorMessage = "Es ist nicht die gleiche Anzahl von xen und yen vorhanden.";
folded = false;
}
}
catch (Exception)
{
errorMessage= "Es trat ein unerwarteter Fehler auf";
folded = false;
}
return folded;
}
First of all, i suggest you to use System.Windows.Media.Imaging.BitmapImage rather than System.Drawing.Image since you are in the WPF-World.
After you changed that, you can easily write
preview.BeginInit();
preview.StreamSource = stream;
preview.EndInit();
after the PngExporter did its job.
Unfortunately i cannot test it since i dont have your pointX and pointY - Collections.
Let me know if that helps
Looks like you want Image.FromStream(stream)

Categories