We're having a requirement to build an OS independent application where we need to draw Rectangles, Lines and Ellipse.
We are developing in a ASP.Net Core (MVC) application to realize the OS independence.
Our ideal situation is to prefix the drawing objects in a model class (height, width, color) and request the objects in the controller or razor view to show them on the web page.
We've searched on the internet and found several options with a BitMap of System.Drawing.Common.
The most common solution is a form application witch we want to avoid, because it isn't OS independent.
What is the best suggestion to realize our situation?
We are not afraid to try the combination of C#, JS HTML and so one, only requirement it needs to fit in the ASP.Net Core application.
Have a look at fabric.js for interacting with the html canvas.
You can develop directly with the canvas, but it will be much easier to use a library that already handles all the heavy lifting.
see: http://fabricjs.com
What about <canvas> ?
The HTML <canvas> element is used to draw graphics on a web page.
var c=document.getElementById("myCanvas");
var canvOK=1;
try {c.getContext("2d");}
catch (er) {canvOK=0;}
if (canvOK==1)
{
var ctx=c.getContext("2d");
ctx.fillStyle="#FF0000";
ctx.fillRect(20,20,100,50);
var grd=ctx.createLinearGradient(140,20,240,70);
grd.addColorStop(0,"black");
grd.addColorStop(1,"white");
ctx.fillStyle=grd;
ctx.fillRect(140,20,100,50);
var grd2=ctx.createLinearGradient(20,90,120,90);
grd2.addColorStop(0,"black");
grd2.addColorStop("0.3","magenta");
grd2.addColorStop("0.5","blue");
grd2.addColorStop("0.6","green");
grd2.addColorStop("0.8","yellow");
grd2.addColorStop(1,"red");
ctx.fillStyle=grd2;
ctx.fillRect(20,90,100,50);
ctx.font="30px Verdana";
var grd3=ctx.createLinearGradient(140,20,240,90);
grd3.addColorStop(0,"black");
grd3.addColorStop("0.3","magenta");
grd3.addColorStop("0.6","blue");
grd3.addColorStop("0.8","green");
grd3.addColorStop(1,"red");
ctx.strokeStyle=grd3;
ctx.strokeText("Smile!",140,120); }
<canvas id="myCanvas" width="270" height="160" style="border:1px solid #c3c3c3;float:left;margin-right:20px;margin-bottom:15px">
Your browser does not support the <canvas> element.
</canvas>
The graphic to the above is created with ''. It shows four elements: a red rectangle, a gradient rectangle, a multicolor rectangle, and a multicolor text.
What is HTML Canvas?
The HTML <canvas> element is used to draw graphics, on the fly, via JavaScript.
The <canvas> element is only a container for graphics. You must use JavaScript to actually draw the graphics.
Canvas has several methods for drawing paths, boxes, circles, text, and adding images.
for complete view
https://www.w3schools.com/html/html5_canvas.asp
https://stackoverflow.com/search?q=canvas
I am trying to achieve a similar objective in an asp.net core 2.0 project. From my ".cshtml" razor view, I am calling a Typescript routine to handle to GUI complexity. Within the view, I am using a HTML5 canvas on which I want to draw rectangles over a background image.
[jsFiddle][1] seems to be the best website to understanding the various interaction of these aspects (HTML, CSS, TypeScript), specifically these examples:
Creating circles with a mouse
Circle drawing in fabricjs
Currently, I not 100% sure how to include "Fabric.js" within the project "wwwroot" directory (or other locations within the project) and secondly how to maintain the background image throughout the drawing of circles, lines etc.
This seems to align with all the responses above. I do know that "System.Drawing" are not available within ".NET Core 2.0" (even via a NuGet package), so unfortunately other methods need to be pursued.
Related
I'm making an app for Windows 8.1 where it is important to be able to zoom in and examine images in detail. If I just open up the bitmap and zoom in it looks like.
However when I load the image into my app and use the ScrollViewer to zoom in I get.
As it appears to be trying to interpolate pixel values for some sort of anti-aliasing.
How can I get it so that when I zoom in it shows (as best it can) the exact pixels of the image? In particular I'm using the image as the background to a canvas which is contained in a scroll viewer.
I've looked around on here and MSDN and found a pair of related questions, but as yet they don't seem to have solved my exact problem.
A discussion on WPF
A similar issue with a canvas
Older related question on pixel art
A way to use bitmap encoding (which I couldn't get to work)
Similarly phrased question
There is no easy way to go about this, your best option is to use DirectX to render the image much larger so that you can mitigate the effect of WinRT automatically interpolating pixel values.
As someone explained on MSDN and based on this outstanding request I can't see any other way to accomplish this.
Use Win2D
Win2D is a DirectX inter-op library for WinRT. With this you can render the image at a much larger size, and then set the default zoom level for the scrollViewier to be very small. Because of this when you zoom in it will appear to be that you can see the individual pixels without any fuzzy/blurry interpolation because you will actually be seeing groups of 64 pixels or so all as one color. I couldn't find any way to actually override what kind of interpolation gets done so this seems to be the best method.
Download Win2D as a NuGet package using Visual Studio, Win2D's
quickstart guide does a good job explaining some of the setup
Set up your canvas and the draw event and use the DrawImage function to render the image larger
<ScrollViewer x:Name="Scroller" ZoomMode="Enabled"
MinZoomFactor="0.1" MaxZoomFactor="20">
<canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" CreateResources="create"/>
</ScrollViewer>
In the canvas_draw function.
canvas.Width = original.Width * 10;
canvas.Height = original.Height * 10;
args.DrawingSession.DrawImage(bitmap,new Rect(0,0,original.Width*10,original.Height*10), new Rect(0,0,original.Width,original.Height), 1.0f, CanvasImageInterpolation.NearestNeighbor);
Make sure to set your canvas to be larger as well
In your code behind set the default zoom of your ScrollVieiwer to be appropriate so your image appears to be the same size.
In the page constructor
Scroller.ZoomToFactor (0.1f);
Other Ways Which I Looked Into and Didn't Work
Making the canvas very large and using BitmapEncoder/BitmapDecoder with the interpolation mode set to NearestNeighbor, this introduced lots of visual artifacts even when scaled to a power of 2 size
Render options only appear to be usable in WPF and not WinRT
It may also be possible to use some image manipulation library to simply make the bitmap 10x or so as large and then use that, but I ended up using Win2D instead.
I am trying to get a feel for the best practice for FormState icons(or icons in general) on a WPF form.
The reason I ask is because when I originally created my Min/Max/Restore/Close buttons I created a few different implementations thinking one would be obvious when they were done. I first created them using the same method as modern UI by MahApps. Using datapoints in the xaml to draw them. I then created my own in illustrator by tracing them from Visual Studio 2012 and then saved them as SVG's. My third approach was after another mentioned they were using the Merlott font in house.
After looking in to using the merlott font I found an answer on the same topic. The answer said that using the Merlott font was best practice and to avoid using the path data points. The answer can be seen here: Making WPF applications look Metro-styled, even in Windows 7?
So this made me even question it even more. What I decided on was using the Scalable Vector Graphics(SVG format).
From there I was able to convert the graphic in Blend Design into pure XAML. It renders the shapes using geometry.
So at this point I have 4 different ways of completing this task. Each one around the same difficulty.
Scalable Vector Graphics - Retraced the shapes in illustrator and exported to pure scalable vector graphics and use the .svg as a resource.
Geometry/XAML - Converted the SVG directly to XAML. This implementation uses geometry to render the shapes.
Path Datapoints - Uses another XAML approach to draw the icons.
Windows Font(Merlott) - This has been around for ages and some think this is the best practice. Normally I would think this isn't a viable option unless including font with project, but Merlott is installed on Windows by default.
So this leaves me with quite a bit of confusion. I have these 4 implementations, all easy enough to implement and no idea which one is the best practice.
Some may think this is subjective, and possibly anal. Although I would like to use best practices on this project(and future projects).
Could anyone care to explain which one would be the better option, and why?
It seems that this tool is perfect for you:
https://github.com/BerndK/SvgToXaml
It can browse svg files and can convert them (without using other tools like inkscape or illustrator). It can also create a single xaml file for all svgs in a folder (batch). The you just have to refer the created object like this and you are golden:
<Button>
<Image Source="{StaticResource cloud_3_iconDrawingImage}"/>
</Button>
Sample app is included.
To answer your question (4 options?)
Option 1 is not possible out of the box (a solution could be https://sharpvectors.codeplex.com/)
Option 2 and 3 seems to be identical - the Path-Object uses a Geometry. To be more precise I prefer using an Image not a Path, because Image has clipping and can contain several PathGeometries with several Colors. The Image can handle MouseClicks better than a Path.
The result can look like this:
<DrawingImage x:Key="cloud_3_iconDrawingImage">
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V512 H512 V0 H0 Z">
<GeometryDrawing Brush="#FF000000" Geometry="F1 M512,512z M0,0z M409.338,216.254C398.922,161.293 350.672,120.477 293.557,120.477 258.459,120.477 225.926,135.762 203.686,162.061 166.538,152.155 127.607,173.842 116.753,210.84 78.16,222.176 50.6,257.895 50.6,299.303 50.6,350.155 91.97,391.524 143.822,391.524L369.18,391.524C420.03,391.524 461.401,350.155 461.401,299.303 461.4,263.389 440.941,231.457 409.338,216.254z M369.18,351.523L143.821,351.523C114.026,351.523 90.599,328.097 90.599,299.302 90.599,265.224 118.249,239.224 152.785,245.486 141.249,205.89 196.916,183.556 217.426,213.138 222.583,198.556 243.249,160.476 293.557,160.476 331.584,160.476 370.918,186.556 372.221,245.458 397.584,245.556 421.401,263.89 421.401,299.302 421.4,328.098 397.975,351.523 369.18,351.523z" />
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
Note this is the definition of the "Image/Icon" to be stored somewhere in the resources. To show it use it as ImageSource with an image as shown above.
Option 4: I think there are only some icons given there, not my preferred solution, but perhaps I understood your idea with the font wrong.
I have some x and y positions in a database table, that go to make up a design for a window.
What I would like to do is draw this onto a HTML5 canvas in my app, but I'm not sure what the best way is to pass data out of my database into the canvas object (I'm not really a JavaScript/web guy).
It will just be drawing lines, that i can do but I'm not sure the best way to get the data into the canvas so I can draw it.
A quick fiddle page for you, maybe this can get you started.
http://dotnetfiddle.net/D3OqTy
I recommend read some html5 canvas tutorial
http://www.html5canvastutorials.com/
I'm a beginner of C#/ASP.NET
Could you please recommend some components for me?
-Here is my scenario.
Load an image file on page.
Add some points(just circle shape) on the image.
Move these points on image.
Get coordination(x, y) of points.
Store the coordination to database.
which component is appropriate for this web page?
It doen't matter using standard asp.net component or devexpress component.
I really appreciate your help.
Take a look at the HTML 5 Canvas drawImage + getMousePos
I used jquery draggable object to implement this.
Here is the link about draggable object.
http://gabrieleromanato.name/jquery-getting-the-coordinates-of-a-draggable-object/
I'm writing a WinForms .NET program that needs to lay some text out on a page (with a few basic geometric/vector graphics). Is there an equivalent of OS X's Core Graphics and/or Core Text? So far, I am just using a PrintDocument and using the Graphics object provided by the PrintPageEventArgs to draw text on the page, but there's very little control over things such as interword spacing, interline spacing etc. and a lot of stuff has to be done manually.
I feel like I'm missing something; is there a better way for typesetting text on a page? I don't mind using 3rd party solutions as long as they are free for personal use.
This will be used for typesetting a small variety of documents, including one-page brochures/fliers (where most text is variable but images are static), award certificates (where most text and images are static but some text is variable), timetables, etc.
WinForms
When you use WinForms it is close to impossible to do proper type setting and yes, almost everything must be done manually. There are a couple of reasons for this:
You don't get detailed glyph information
The text measurement is horrible inaccurate, both the GDI+ and the GDI based version.
Windows Presentation Foundation
If you use WPF this is an entirely different matter as you get detailed geometrical information about each glyph.
However, you can interleave the two, a bit messy, but possible. Although, I do not recommend it as the graphics and bitmaps are not directly interchangeable which can result in slow performance.
If you want to look at the possibility you need to import the System.Windows.Media into your project to access the typeface and glyph capability of WPF.
You will meet a couple of other challenges as well:
The font lists between WinForm and WPF are not identical (more font and font types with WPF).
You cannot just use a WPF glyph and draw it to a WinForm bitmap.
The values from the glyph are, as expected, in em so they need to be converted to pixels based on point size.
However, you can get this (not limited to) information:
All details (too many to list here):
http://msdn.microsoft.com/en-us/library/system.windows.media.glyphtypeface.aspx
Conclusion
But if you stick with GDI+ and WinForms the best approach you can take is probably to use the GDI based TextMetrics class.
You will in any case experience possibly padding issues, you cannot set char spacing and so forth.
You will have to calculate baseline for each typeface and size by using top + ascent:
FontFamily ff = myFont.FontFamily;
float lineSpace = ff.GetLineSpacing(myFont.Style);
float ascent = ff.GetCellAscent(myFont.Style);
float baseline = myFont.GetHeight(ev.Graphics) * ascent / lineSpace;
PointF renderPt = new PointF(pt.X, pt.Y - baseline));
ev.Graphics.DrawString("My baselined text", myFont, textBrush, renderPt);
I do not know of any third-party library that can do this within the WinForm environment, I believe for the reasons mentioned here and the pain it would cause.
In conclusion I can only recommend you to take a look at Windows Presentation Foundation/WPF for a better ground to achieve proper type setting as you will get stuck in a lot of compromises using WinForms for this (I made a font viewer which is where I came across WPF as I wanted to show glyphs and detailed information about it including black-box and so forth - that was painful enough).
UPDATE:
WebBrowser as type-setting engine
A possible work-around of this is to use the WebBrowser control to do the setting. It's not an actual hack, but a bit hack-ish as it establish a initially unnecessary dependency on the IE browser on the user's computer.
However, this can turn out to be flexible when it comes to type setting as you have the same simple controls over text as with any HTML page.
To get a result you attach the HTML with styles and attributes for the text. You can even combine it with images and so forth (obviously).
The control can be for example on another hidden form not visible to the user.
After dropping in the WebControl on the form or creating it manually setting HTML is done in a single step:
WebBrowser1.DocumentText = "<span style='font-size:24px;'>Type-setting</span> <span style='font-family:sans-serif;font-size:18px;font-style:italic;'>using the browser component.</span>";
Next step is to grab what you render as HTML as an image which can be done as this:
using mshtml;
using System.Drawing;
using System.Runtime.InteropServices;
[ComImport, InterfaceType((short)1), Guid("3050F669-98B5-11CF-BB82-00AA00BDCE0B")]
private interface IHTMLElementRenderFixed
{
void DrawToDC(IntPtr hdc);
void SetDocumentPrinter(string bstrPrinterName, IntPtr hdc);
}
public Bitmap GetImage(string id)
{
HtmlElement e = webBrowser1.Document.GetElementById(id);
IHTMLImgElement img = (IHTMLImgElement)e.DomElement;
IHTMLElementRenderFixed render = (IHTMLElementRenderFixed)img;
Bitmap bmp = new Bitmap(e.OffsetRectangle.Width, e.OffsetRectangle.Height);
Graphics g = Graphics.FromImage(bmp);
IntPtr hdc = g.GetHdc();
render.DrawToDC(hdc);
g.ReleaseHdc(hdc);
return bmp;
}
From: Saving images from a WebBrowser Control
Now you can place the bitmap on to your normal page. ..Or just use the control directly on the form with reduced interactive capability (right-click menu could easily become a problem if not).
Not knowing the exact usage that this is for, this may or may not be a suitable solution but it gives some powerful options and can be in place of a third-party solution.
Components
Looking high and low it seem that this area is not so much targeted. I could find one component that comes close but the pattern continues: one will be hitting a nail with a sledgehammer. It ends up in the same category as the WebBrowser work-around.
This component is really a full fledged editor but by disabling most of it it can perhaps be used to simply display formatted text/graphics with type setting sort of at hand:
http://www.textcontrol.com/en_US/products/dotnet/overview/
Another possibility is to use a PDF component to set up the content and use a component to render the PDF as graphics (commercial):
http://www.dynamicpdf.com/Generate-PDF-.NET.aspx
http://www.dynamicpdf.com/Rasterizer-PDF-.NET.aspx
Non-commercial:
http://www.pdfsharp.net/?AspxAutoDetectCookieSupport=1
Using GhostScript to get image:
http://www.codeproject.com/Articles/32274/How-To-Convert-PDF-to-Image-Using-Ghostscript-API
The obvious static alternative
..and corky perhaps, but in any case I'll include it as simplicity sometimes works best -
If it is not a absolute requirement to be able to create these pages dynamically, generate all the text and graphics in Illustrator/Photoshop/inDesign etc. and save the result as images to be displayed.
In order to lay down text: there are several possibilities:
A simple label, that lets you simple text manipulation (like font, placement, color, etc.)
A rich text document that you may change the properties of the control to suite your needs, keep in mind that this one may present some simple images, etc.
An image -> that you may create dynamically, with the graphics object, with the onpaint event. this is not recomended, as its a very low level approach, but as you know as low level as you get, the more power you gain.
Combination of many controls, in a custom control you create, that you hold the information you want to draw / write in local members -> then keeping cont to when you change something, then set a flag (_needToBeRepainted = true;), and then on repainting, if(_needToBeRepainted) draw everything.
please let me know if you need further assistance solving this one.