C# .net Core rounded corners for image - c#

I save images from social networks and I want to do rounded corners for image and save it to the database. For example, I got a photo from the facebook by url on my Api and I want to process this image
How it possible on .net Core
Below, what results I expect
Image before:
Image after:

You can use SixLabors.ImageSharp library, it is available for .NET Core:
PM > Install-Package SixLabors.ImageSharp
Here is the sample code:
public static void ApplyRoundedCorners(Image<Rgba32> img, float cornerRadius)
{
IPathCollection corners = BuildCorners(img.Width, img.Height, cornerRadius);
var graphicOptions = new GraphicsOptions(true) { BlenderMode = PixelBlenderMode.Src };
img.Mutate(x => x.Fill(graphicOptions, Rgba32.Transparent, corners));
}
public static IPathCollection BuildCorners(int imageWidth, int imageHeight, float cornerRadius)
{
var rect = new RectangularPolygon(-0.5f, -0.5f, cornerRadius, cornerRadius);
IPath cornerToptLeft = rect.Clip(new EllipsePolygon(cornerRadius - 0.5f, cornerRadius - 0.5f, cornerRadius));
var center = new Vector2(imageWidth / 2F, imageHeight / 2F);
float rightPos = imageWidth - cornerToptLeft.Bounds.Width + 1;
float bottomPos = imageHeight - cornerToptLeft.Bounds.Height + 1;
IPath cornerTopRight = cornerToptLeft.RotateDegree(90).Translate(rightPos, 0);
IPath cornerBottomLeft = cornerToptLeft.RotateDegree(-90).Translate(0, bottomPos);
IPath cornerBottomRight = cornerToptLeft.RotateDegree(180).Translate(rightPos, bottomPos);
return new PathCollection(cornerToptLeft, cornerBottomLeft, cornerTopRight, cornerBottomRight);
}
private static IImageProcessingContext<Rgba32> ConvertToAvatar(this IImageProcessingContext<Rgba32> processingContext, Size size, float cornerRadius)
{
return processingContext.Resize(new ResizeOptions
{
Size = size,
Mode = ResizeMode.Crop
}).Apply(i => ApplyRoundedCorners(i, cornerRadius));
}
And you can use it like this:
using (var img = Image.Load("fb.jpg"))
{
using (Image<Rgba32> destRound = img.Clone(x => x.ConvertToAvatar(new Size(200, 200), 100)))
{
destRound.Save("output/fb-round.png");
}
}
More examples can be found here.

Related

How to convert a image (Texture2D) to tensor

I have c# TensorFlow.NET working in Unity. But it using an image from the file system. I want to be able to use an image from memory (Texture2D).
I tried to follow some examples of people using TensorFlowSharp. But that didn't work.
What am I doing wrong?
Note: with both functions, I am using the same image. The image is 512x512. but the result of both pictures is different.
// Doesn't work
private NDArray FromTextureToNDArray(Texture2D texture) {
Color32[] pixels = texture.GetPixels32();
byte[] floatValues = new byte[(texture.width * texture.height) * 3];
for (int i = 0; i < pixels.Length; i++) {
var color = pixels[i];
floatValues[i * 3] = color.r;
floatValues[i * 3 + 1] = color.g;
floatValues[i * 3 + 2] = color.b;
}
Shape shape = new Shape(1, texture.width, texture.height, 3);
NDArray image = new NDArray(floatValues, shape);
return image;
}
// Works
private NDArray ReadFromFile(string fileName) {
var graph = new Graph().as_default();
// Change image
var file_reader = tf.read_file(fileName, "file_reader");
var decodeJpeg = tf.image.decode_jpeg(file_reader, channels: 3, name: "DecodeJpeg");
var casted = tf.cast(decodeJpeg, TF_DataType.TF_UINT8);
var dims_expander = tf.expand_dims(casted, 0);
using (var sess = tf.Session(graph)) {
return sess.run(dims_expander);
}
}
I ended up using this code from Shaqian: https://github.com/shaqian/TF-Unity/blob/master/TensorFlow/Utils.cs
Add this script to your project and then you could use it like this:
// Get image
byte[] imageData = Utils.DecodeTexture(texture, texture.width, texture.height, 0, Flip.VERTICAL);
Shape shape = new Shape(1, texture.width, texture.height, 3);
NDArray image = new NDArray(imageData, shape);
Use Barracuda as step in between.
var encoder = new Unity.Barracuda.TextureAsTensorData(your_2d_texture);

How to cut slices from a very large image faster using C#?

I have images that could be as big as 20000x20000 pixels in height and width. (Not more than 50 MB). Loading such images into a picture box using C# is very slow and when I need to slice this thing into 200x200 pixels images, it is very slow (few images per second). My current application works fine but very slow and am looking into much faster approaches if available.
This is how I currently loading the image into the image box. (Which is slow too - few seconds to load)
resizedImage = new System.Drawing.Bitmap(OriginalImage, new System.Drawing.Size((int)(OriginalImage.Width * zoomFactor), (int)(OriginalImage.Height * zoomFactor)));
imgBox.Image = resizedImage;
What is the best way to slice this image faster?
This is my current slicing routine .
private void CropSolderJoints()
{
//ordinatesToCrop CordsToCrop = createCordinatesToCrop();
try
{
PB.Maximum = Adjustedcordinates.Pins.Count;
double OriginX = Convert.ToDouble(txtOriginX.Text);
double OriginY = Convert.ToDouble(txtOriginY.Text);
double Scale = Convert.ToDouble(txtScale.Text);
double BumpSize = Convert.ToDouble(txtBumpSize.Text);
Stopwatch watch = new Stopwatch();
watch.Start();
System.Drawing.PointF pos = new System.Drawing.PointF();
double zoomFactor = (float)(double)(Math.Max(imgBox.Width, imgBox.Height) / (double)Math.Max(OriginalImage.Width, OriginalImage.Height));
System.Drawing.Size lensPixelSize = new System.Drawing.Size((int)Math.Round(BumpSize / zoomFactor), (int)Math.Round(BumpSize / zoomFactor));
Rectangle CropJointRectangle = new Rectangle(0, 0, (int)Math.Round(BumpSize / zoomFactor), (int)Math.Round(BumpSize / zoomFactor));
int pinCount = 0;
float radius = (float)(BumpSize) / 2;
foreach (PinCordinates p in Adjustedcordinates.Pins)
{
{
{
PB.Invoke(new MethodInvoker(delegate {
}));
string folderName = new DirectoryInfo(imageFolder).Name;
string filename = dgvImages.SelectedCells[1].Value.ToString();
string Imagefilename = String.Format("{0}_{1}_{2}_{3}", folderName, Path.GetFileNameWithoutExtension(filename), p.defect.ToString(), p.PinLabel);
string saveFilePath = String.Format("{0}\\{1}.{2}", imageFolder, Imagefilename, "png");
float TopLeftX = (float)(OriginX + (float)(p.Cordinates.X * Scale));
float TopLeftY = (float)(OriginY + (float)(p.Cordinates.Y * Scale));
float length = (float)(BumpSize);
float width = (float)(BumpSize);
pos = new System.Drawing.PointF((float)(TopLeftX), (float)(TopLeftY));
imageLens.Location = pkg.GetLensPosition(pos, imageLens);
imageLens.Size = lensUseRelativeSize
? pkg.GetScaledLensSize(imgBox.ClientRectangle, SourceImage.Size, lensPixelSize)
: lensPixelSize;
RectangleF section = pkg.CanvasToImageRect(imgBox.ClientRectangle, SourceImage.Size, imageLens);
Bitmap imgJoint = new Bitmap((int)Math.Round(BumpSize / zoomFactor), (int)Math.Round(BumpSize / zoomFactor));
Graphics g = Graphics.FromImage(imgJoint);
pkg.DrawImageSelection(g, CropJointRectangle, section, SourceImage);
g.DrawImage(imgJoint, 0, 0);
picZoom.Image = imgJoint;
imgJoint.Save(saveFilePath);
PB.Value = pinCount;
pinCount++;
picZoom.Refresh();
}
}
}
PB.Value = 0;
watch.Stop();
label1.Text = watch.Elapsed.TotalSeconds.ToString();
MessageBox.Show("Slicing completed sucessfully." + pinCount.ToString() + "bumps sliced.");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

translate CGContext generating image method from ios to mac

Is anyone able to help me translate this method in ios to mac version? Code is written in C# in Xamarin
public static UIImage GetImageFromColor(UIColor color, float borderWidth = 1.0f)
{
var rect = new CGRect(0.0f, 0.0f, borderWidth, borderWidth);
UIGraphics.BeginImageContext(rect.Size);
var context = UIGraphics.GetCurrentContext();
context.SetFillColor(color.CGColor);
context.FillRect(rect);
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image.CreateResizableImage(new UIEdgeInsets(1.0f, 1.0f, 1.0f, 1.0f));
}
UIGraphics.BeginImageContext translates to a CGBitmapContext (or CGContext depending upon what you need).
So to fill a CGBitmapContext with a color:
var size = new CGSize(width, height);
var rect = new CGRect(new CGPoint(), size);
NSImage image;
using (var context = new CGBitmapContext(IntPtr.Zero, width, height, 8, width * 4, NSColorSpace.GenericRGBColorSpace.ColorSpace, CGImageAlphaInfo.PremultipliedFirst))
{
context.SetFillColor(NSColor.Red.CGColor);
context.FillRect(rect);
using (var cgImage = context.ToImage())
{
image = new NSImage(cgImage, size);
}
}
Note: You should use using or make sure that you Dispose of the context and CGImage to avoid a memory leak
This is not a translation from the code you posted but it does exactly the same job:
public static NSImage GetImageFromColor (NSColor color, float borderWidth = 1.0f)
{
var image = new NSImage (new CGSize (borderWidth, borderWidth));
image.LockFocus ();
color.DrawSwatchInRect (new CGRect (new CGPoint (0, 0), image.Size));
image.UnlockFocus ();
return image;
}
Hope this helps.-

iOS Fit Image to Screen

I have an image that is 646x289 that I am trying to fit in the screen with respect to its aspect ratio.
Here is my current approach:
Controller:
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
_imnLogo.ContentMode = UIViewContentMode.ScaleAspectFit;
_imnLogo.SizeToFit();
_imnLogo.Frame = new CGRect(
View.Bounds.Left + 2 * Globals.MarginGrid,
View.Bounds.Top + Globals.MarginGrid,
_scaledImage.Size.Width, _scaledImage.Size.Height);
}
public override void LoadView()
{
base.LoadView();
_scaledImage = MaxResizeImage(
UIImage.FromFile("imn_logo.png"), (float) View.Bounds.Width, (float) View.Bounds.Height);
_imnLogo = new UIImageView(_scaledImage);
View.AddSubview(_imnLogo);
}
public UIImage MaxResizeImage(UIImage sourceImage, float maxWidth, float maxHeight)
{
var sourceSize = sourceImage.Size;
var maxResizeFactor = Math.Max(maxWidth / sourceSize.Width, maxHeight / sourceSize.Height);
if (maxResizeFactor > 1) return sourceImage;
var width = maxResizeFactor * sourceSize.Width;
var height = maxResizeFactor * sourceSize.Height;
UIGraphics.BeginImageContext(new SizeF((float) width, (float) height));
sourceImage.Draw(new RectangleF(0, 0, (float) width, (float) height));
var resultImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return resultImage;
}
When this loads, the image is way too large and doesn't fit in the screen.
I am constructing all of my interfaces in C# (using Xamarin) as well so I need to be able to do this using frames and bounds.
Use the ContentMode of the UIImageView to control how the image is scaled and you can skip the manual resizing:
public override void LoadView()
{
base.LoadView();
_imnLogo = new UIImageView(UIImage.FromFile("imn_logo.png"));
_imnLogo.Frame = View.Frame;
_imnLogo.ContentMode = UIViewContentMode.ScaleAspectFill;
View.AddSubview(imageView);
View.SendSubviewToBack(imnLogo); // Do this if you want to place other `View`s on top of the logo...
}
Ref: https://developer.apple.com/reference/uikit/uiviewcontentmode

Text is blurred when transformed in WPF

I'm using DrawingContext.DrawText and DrawingContext.PushTransfrom to create rotated text on Visual Layer in WPF but as you see in the image below, the rotated text is rather blurry in some areas of the image..
Is there any option I can use to improve this? The Arial font is used for the text.
public class BeamTextDrawing : FrameworkElement
{
private readonly VisualCollection _visuals;
public BeamTextDrawing(double scale)
{
if (scale <= 0)
{
scale = 1;
}
var typeface = Settings.BeamTextTypeface;
var cultureinfo = Settings.CultureInfo;
var flowdirection = Settings.FlowDirection;
var textsize = Settings.BeamTextSize / scale;
var beamtextcolor = Settings.InPlanBeamTextColor;
_visuals = new VisualCollection(this);
foreach (var beam in Building.BeamsInTheElevation)
{
var drawingVisual = new DrawingVisual();
using (var dc = drawingVisual.RenderOpen())
{
var text = Convert.ToString(beam.Section.Id);
//text = scale.ToString();
var ft = new FormattedText(text, cultureinfo, flowdirection,
typeface, textsize, beamtextcolor)
{
TextAlignment = TextAlignment.Center
};
var x1 = beam.ConnectivityLine.I.X;
var y1 = beam.ConnectivityLine.I.Y;
var x2 = beam.ConnectivityLine.J.X;
var y2 = beam.ConnectivityLine.J.Y;
var v1 = new Point(x2, y2) - new Point(x1, y1);
var v2 = new Vector(1, 0);
var hwidth = textsize;
var l = Geometrics.GetOffset(x1, y1, x2, y2, hwidth + 5/scale);
var angle = Vector.AngleBetween(v1, v2);
var x = 0.5 * (l.X1 + l.X2);
var y = 0.5 * (l.Y1 + l.Y2);
var r = new RotateTransform(angle, x, SelectableModel.FlipYAxis(y));
dc.PushTransform(r);
dc.DrawText(ft, SelectableModel.FlipYAxis(x, y));
}
_visuals.Add(drawingVisual);
}
}
protected override Visual GetVisualChild(int index)
{
return _visuals[index];
}
protected override int VisualChildrenCount
{
get
{
return _visuals.Count;
}
}
}
Update:
Here is the image after using this code:
TextOptions.SetTextFormattingMode(this, TextFormattingMode.Display);
I'm still getting blurry results. Look at the middle beam text at the lower part of the image.
Check out this article - Pixel Snapping in WPF Applications
Since WPF uses device independent pixels it can create irregular edge rendering due to anti-aliasing when it undergoes transformation. Pixel snapping is a means to suppress these visual artifacts by applying small offsets to the geometry of the visual to align the geometry to device pixels.
Setting the SnapsToDevicePixels Property to "True" for your UI elements should be able to fix your issue.

Categories

Resources