How can I build slanted dashed line in Xamarin application - xamarin

I want to display a slanted dashed line in my application that would look something like
this. using Line API in xamarin I was able to create dashed line, but I haven't had any luck with making each dash slanted. I also looked at skiasharp library for Xamarin but didn't find anything which can help with slanting.

#jason thank you for your response, I was so much focused on getting "Slanted dashed line" what you suggested never crossed my mind. Although now I have the solution for my issue.
public partial class SlantedDashedView : ContentView
{
private readonly SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Fill,
Color = Color.Red.ToSKColor()
};
private readonly SKRect rect = new SKRect
{
Location = new SKPoint(0, 0),
Size = new SKSize(25, 30)
};
public SlantedDashedView()
{
InitializeComponent();
mainCanvas.InvalidateSurface();
}
private void MainCanvas_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
SKImageInfo info = e.Info;
SKSurface surface = e.Surface;
SKCanvas canvas = surface.Canvas;
int currentY = 0;
canvas.Skew(0, -1);
while (currentY < info.Height)
{
canvas.DrawRect(rect, paint);
currentY += 45;
canvas.Translate(0, 45);
}
}
}
Here is the result

Related

Adding a bottom border to an Entry in Xamarin Forms iOS with an image at the end

Now before anyone ignores this as a duplicate please read till the end. What I want to achieve is this
I've been doing some googling and looking at objective c and swift responses on stackoverflow as well. And this response StackOverFlowPost seemed to point me in the right direction. The author even told me to use ClipsToBounds to clip the subview and ensure it's within the parents bounds. Now here's my problem, if I want to show an image on the right side of the entry(Gender field), I can't because I'm clipping the subview.
For clipping, I'm setting the property IsClippedToBounds="True" in the parent stacklayout for all textboxes.
This is the code I'm using to add the bottom border
Control.BorderStyle = UITextBorderStyle.None;
var myBox = new UIView(new CGRect(0, 40, 1000, 1))
{
BackgroundColor = view.BorderColor.ToUIColor(),
};
Control.AddSubview(myBox);
This is the code I'm using to add an image at the beginning or end of an entry
private void SetImage(ExtendedEntry view)
{
if (!string.IsNullOrEmpty(view.ImageWithin))
{
UIImageView icon = new UIImageView
{
Image = UIImage.FromFile(view.ImageWithin),
Frame = new CGRect(0, -12, view.ImageWidth, view.ImageHeight),
ClipsToBounds = true
};
switch (view.ImagePos)
{
case ImagePosition.Left:
Control.LeftView.AddSubview(icon);
Control.LeftViewMode = UITextFieldViewMode.Always;
break;
case ImagePosition.Right:
Control.RightView.AddSubview(icon);
Control.RightViewMode = UITextFieldViewMode.Always;
break;
}
}
}
After analysing and debugging, I figured out that when OnElementChanged function of the Custom Renderer is called, the control is still not drawn so it doesn't have a size. So I subclassed UITextField like this
public class ExtendedUITextField : UITextField
{
public UIColor BorderColor;
public bool HasBottomBorder;
public override void Draw(CGRect rect)
{
base.Draw(rect);
if (HasBottomBorder)
{
BorderStyle = UITextBorderStyle.None;
var myBox = new UIView(new CGRect(0, 40, Frame.Size.Width, 1))
{
BackgroundColor = BorderColor
};
AddSubview(myBox);
}
}
public void InitInhertedProperties(UITextField baseClassInstance)
{
TextColor = baseClassInstance.TextColor;
}
}
And passed the hasbottomborder and bordercolor parameters like this
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
var view = e.NewElement as ExtendedEntry;
if (view != null && Control != null)
{
if (view.HasBottomBorder)
{
var native = new ExtendedUITextField
{
BorderColor = view.BorderColor.ToUIColor(),
HasBottomBorder = view.HasBottomBorder
};
native.InitInhertedProperties(Control);
SetNativeControl(native);
}
}
But after doing this, now no events fire :(
Can someone please point me in the right direction. I've already built this for Android, but iOS seems to be giving me a problem.
I figured out that when OnElementChanged function of the Custom Renderer is called, the control is still not drawn so it doesn't have a size.
In older versions of Xamarin.Forms and iOS 9, obtaining the control's size within OnElementChanged worked....
You do not need the ExtendedUITextField, to obtain the size of the control, override the Frame in your original renderer:
public override CGRect Frame
{
get
{
return base.Frame;
}
set
{
if (value.Width > 0 && value.Height > 0)
{
// Use the frame size now to update any of your subview/layer sizes, etc...
}
base.Frame = value;
}
}

Custom Font in Xamarin.Forms Label with FormattedString

I have created a custom LabelRenderer in my Android app to apply a custom font in a Xamarin Android app (https://developer.xamarin.com/guides/xamarin-forms/user-interface/text/fonts/).
Everything works great for a normal label with the content added to the .Text property. However, if I create a label using .FormattedText property, the custom font is not applied.
Anyone have success doing this? An option, since I'm just stacking lines of different sized text, is to use separate label controls for each, but I'd prefer to use a formatted string if possible.
Here's the guts of my custom renderer:
[assembly: ExportRenderer (typeof (gbrLabel), typeof (gbrLabelRenderer))]
public class gbrLabelRenderer: LabelRenderer
{
protected override void OnElementChanged (ElementChangedEventArgs<Label> e)
{
base.OnElementChanged (e);
var label = (TextView)Control;
Typeface font = Typeface.CreateFromAsset (Forms.Context.Assets, "Lobster-Regular.ttf");
label.Typeface = font;
}
}
And here's my simple label control... all it does is apply the font to iOS, and leaves applying the font for Android up to the custom renderer.
public class gbrLabel: Label
{
public gbrLabel ()
{
Device.OnPlatform (
iOS: () => {
FontFamily = "Lobster-Regular";
FontSize = Device.GetNamedSize(NamedSize.Medium,this);
}
}
}
Works fine for labels with just the .Text property... but not for labels with the .FormattedText property.
Should I keep digging, or just stack my labels since that's an option in this case?
Here's an example of the various ways I've tried this in the Formatted text, since that was requested:
var fs = new FormattedString ();
fs.Spans.Add (new Span {
Text = string.Format("LINE 1\n",Title),
FontSize = Device.GetNamedSize(NamedSize.Large,typeof(Label))
});
fs.Spans.Add (new Span {
Text = string.Format ("LINE 2\n"),
FontSize = Device.GetNamedSize(NamedSize.Large,typeof(Label)) * 2,
FontAttributes = FontAttributes.Bold,
FontFamily = "Lobster-Regular"
});
fs.Spans.Add (new Span {
Text = string.Format ("LINE 3\n"),
FontSize = Device.GetNamedSize(NamedSize.Medium,typeof(Label)),
FontFamily = "Lobster-Regular.ttf"
});
gbrLabel lblContent = new gbrLabel {
FormattedText = fs
}
None of these (the first should be set by the default class / renderer, and the second 2 are variations of including the font in a span definition itself) work on Android.
Note: Android and iOS issues have been summarized on a blog post: smstuebe.de/2016/04/03/formattedtext.xamrin.forms/
The font is set as long as you do not set FontSize or FontAttributes. So I had the look at the implementation and found that the FormattedText is trying to load the font like the default renderer which doesn't work on Android.
The android formatting system works very similar to that one of Xamarin.Forms. It's using spans to define text attributes. The renderer is adding a FontSpan for every Span with a custom font, size or attribute. Unfortunately, the FontSpanclass is a private inner class of FormattedStringExtensions so we have to deal with reflections.
Our Renderer is updating the Control.TextFormatted on initialization and when the FormattedText property changes. In the update method, we get all FontSpans and replace them with our CustomTypefaceSpan.
Renderer
public class FormattedLabelRenderer : LabelRenderer
{
private static readonly Typeface Font = Typeface.CreateFromAsset(Forms.Context.Assets, "LobsterTwo-Regular.ttf");
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
Control.Typeface = Font;
UpdateFormattedText();
}
private void UpdateFormattedText()
{
if (Element.FormattedText != null)
{
var extensionType = typeof(FormattedStringExtensions);
var type = extensionType.GetNestedType("FontSpan", BindingFlags.NonPublic);
var ss = new SpannableString(Control.TextFormatted);
var spans = ss.GetSpans(0, ss.ToString().Length, Class.FromType(type));
foreach (var span in spans)
{
var start = ss.GetSpanStart(span);
var end = ss.GetSpanEnd(span);
var flags = ss.GetSpanFlags(span);
var font = (Font)type.GetProperty("Font").GetValue(span, null);
ss.RemoveSpan(span);
var newSpan = new CustomTypefaceSpan(Control, font);
ss.SetSpan(newSpan, start, end, flags);
}
Control.TextFormatted = ss;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Label.FormattedTextProperty.PropertyName)
{
UpdateFormattedText();
}
}
}
I'm not sure, why you introduced a new element type gbrLabel, but as long as you only wan't to change the renderer, you don't have to create a custom element. You can replace the renderer of the default element:
[assembly: ExportRenderer(typeof(Label), typeof(FormattedLabelRenderer))]
CustomTypefaceSpan
public class CustomTypefaceSpan : MetricAffectingSpan
{
private readonly Typeface _typeFace;
private readonly Typeface _typeFaceBold;
private readonly Typeface _typeFaceItalic;
private readonly Typeface _typeFaceBoldItalic;
private readonly TextView _textView;
private Font _font;
public CustomTypefaceSpan(TextView textView, Font font)
{
_textView = textView;
_font = font;
// Note: we are ignoring _font.FontFamily (but thats easy to change)
_typeFace = Typeface.CreateFromAsset(Forms.Context.Assets, "LobsterTwo-Regular.ttf");
_typeFaceBold = Typeface.CreateFromAsset(Forms.Context.Assets, "LobsterTwo-Bold.ttf");
_typeFaceItalic = Typeface.CreateFromAsset(Forms.Context.Assets, "LobsterTwo-Italic.ttf");
_typeFaceBoldItalic = Typeface.CreateFromAsset(Forms.Context.Assets, "LobsterTwo-BoldItalic.ttf");
}
public override void UpdateDrawState(TextPaint paint)
{
ApplyCustomTypeFace(paint);
}
public override void UpdateMeasureState(TextPaint paint)
{
ApplyCustomTypeFace(paint);
}
private void ApplyCustomTypeFace(Paint paint)
{
var tf = _typeFace;
if (_font.FontAttributes.HasFlag(FontAttributes.Bold) && _font.FontAttributes.HasFlag(FontAttributes.Italic))
{
tf = _typeFaceBoldItalic;
}
else if (_font.FontAttributes.HasFlag(FontAttributes.Bold))
{
tf = _typeFaceBold;
}
else if (_font.FontAttributes.HasFlag(FontAttributes.Italic))
{
tf = _typeFaceItalic;
}
paint.SetTypeface(tf);
paint.TextSize = TypedValue.ApplyDimension(ComplexUnitType.Sp, _font.ToScaledPixel(), _textView.Resources.DisplayMetrics);
}
}
Our Custom CustomTypefaceSpanis similar to the FontSpan of Xamarin.Forms, but is loading the custom fonts and can load different fonts for different FontAttributes.
The result is a nice colorful Text :)

SwapChainBackgroundPanel letterboxing Monogame Windows Store App

I am porting my space shooter game from Windows Phone to Windows Store App. In WP it always play in full portrait orientation.
For the Windows Store app though while in landscape mode, I want to center the game screen with letterboxing on the left and right. The problem is I can't adjust the margin property of SwapChainBackgroundPanel so the game always aligned to the left and the black screen is on the right.
Here's my code
public Game1()
{
graphics = new GraphicsDeviceManager(this);
GamePage.Current.SizeChanged += OnWindowSizeChanged;
Content.RootDirectory = "Content";
}
private void OnWindowSizeChanged(object sender, Windows.UI.Xaml.SizeChangedEventArgs e)
{
var CurrentViewState = Windows.UI.ViewManagement.ApplicationView.Value;
double width = e.NewSize.Width;
double height = e.NewSize.Height;
// using Windows.Graphics.Display;
ResolutionScale resolutionScale = DisplayProperties.ResolutionScale;
string orientation = null;
if (ApplicationView.Value == ApplicationViewState.FullScreenLandscape)
{
orientation = "FullScreenLandscape";
//Does not work because it's start on the center of the screen
//Black screen is on the left and place the game screen on the right
GamePage.Current.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center;
//Gives error - WinRT information: Setting 'Margin' property is
//not supported on SwapChainBackgroundPanel.
GamePage.Current.Margin = new Thickness(centerMargin, 0, 0, 0);
}
else if (ApplicationView.Value == ApplicationViewState.FullScreenPortrait)
{
orientation = "FullScreenPortrait";
}
else if (ApplicationView.Value == ApplicationViewState.Filled)
{
orientation = "Filled";
}
else if (ApplicationView.Value == ApplicationViewState.Snapped)
{
orientation = "Snapped";
}
Debug.WriteLine("{0} x {1}. Scale: {2}. Orientation: {3}",
width.ToString(), height.ToString(), resolutionScale.ToString(),
orientation);
}
The GamePage.xaml is the default
<SwapChainBackgroundPanel
x:Class="SpaceShooterXW8.GamePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SpaceShooterXW8"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
</SwapChainBackgroundPanel>
After some researched I think I've figured it out thanks to this blog post. To those who are in a similar situation, here's what I did.
The beauty of the solution is that the letterboxing is automatically managed by the Resolution class. All I have to do is update the batch.begin() lines in my code to something like
batch.Begin(SpriteSortMode.Deferred,
null, SamplerState.LinearClamp,
null,
null,
null,
Resolution.getTransformationMatrix());
To handle resolution changes as the orientation changed I use this in my Game1.cs
public Game1()
{
graphics = new GraphicsDeviceManager(this);
GamePage.Current.SizeChanged += OnWindowSizeChanged;
Content.RootDirectory = "Content";
Resolution.Init(ref graphics);
Resolution.SetVirtualResolution(480, 800);
}
private void OnWindowSizeChanged(object sender, Windows.UI.Xaml.SizeChangedEventArgs e)
{
var CurrentViewState = Windows.UI.ViewManagement.ApplicationView.Value;
App.AppWidth = (int)e.NewSize.Width;
App.AppHeight = (int)e.NewSize.Height;
Resolution.SetResolution(App.AppWidth, App.AppHeight, true);
}
The initial values of App.AppWidth and App.AppHeight is set in the GamePage.xaml.cs.
public GamePage(string launchArguments)
{
this.InitializeComponent();
App.AppWidth = (int)Window.Current.Bounds.Width;
App.AppHeight = (int)Window.Current.Bounds.Height;
Current = this;
// Create the game.
_game = XamlGame<Game1>.Create(launchArguments, Window.Current.CoreWindow, this);
}
Both are global static property created in the App.xaml.cs
public static int AppWidth { get; set; }
public static int AppHeight { get; set; }
The only problem I've encountered so far, the mouse input does not scale to the screen resolution change. I do not have a touch screen to test unfortunately but I think touch input should scale. If anyone tested touch, please share your findings. Thanks.
Update
I've managed to scale the Mouse input using the following
public static Vector2 ScaleGesture(Vector2 position)
{
int x = (int)(position.X / (float)App.AppWidth * (float)Screen.ScreenWidth);
int y = (int)(position.Y / (float)App.AppHeight * (float)Screen.ScreenHeight);
var scaledPosition = new Vector2(x, y);
return scaledPosition;
}

SlimDX Handling Window Resizing

I'm trying to handle the program window being resized, and the (I think inefficient) code I've flung together below seems to do the trick.
Is there a better way to do this, preferably one that does not create a stutter when resizing the window and which does not constantly use 12-17% of a CPU? I also suspect MessagePump.Run may somehow run before form.Resize finishes setting up the device again, and throw an error.
Thanks!
using System;
using System.Drawing;
using System.Windows.Forms;
using SlimDX;
using SlimDX.Direct3D9;
using SlimDX.Windows;
namespace SlimDX_1
{
struct Vertex
{
public Vector4 Position;
public int Color;
}
static class Program
{
private static VertexBuffer vertices;
private static Device device;
private static RenderForm form;
private static PresentParameters present;
private static VertexDeclaration vertexDecl;
private static VertexElement[] vertexElems;
private static bool wasMinimized = false;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
form = new RenderForm("Tutorial 1: Basic Window");
init();
form.Resize += (o, e) =>
{
if (form.WindowState == FormWindowState.Minimized)
{
foreach (var item in ObjectTable.Objects)
{
item.Dispose();
}
wasMinimized = true;
}
else
{
foreach (var item in ObjectTable.Objects)
{
item.Dispose();
}
init();
device.SetRenderState(RenderState.FillMode, FillMode.Wireframe);
device.SetRenderState(RenderState.CullMode, Cull.None);
present.BackBufferHeight = form.ClientSize.Height;
present.BackBufferWidth = form.ClientSize.Width;
device.Reset(present);
}
};
MessagePump.Run(form, () =>
{
if (form.WindowState == FormWindowState.Minimized)
{
return;
}
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);
device.BeginScene();
device.SetStreamSource(0, vertices, 0, 20); // 20 is the size of each vertex
device.VertexDeclaration = vertexDecl;
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
device.EndScene();
device.Present();
});
foreach (var item in ObjectTable.Objects)
{
item.Dispose();
}
}
private static void init()
{
present = new PresentParameters();
//present.EnableAutoDepthStencil = false;
//present.BackBufferCount = 1;
//present.SwapEffect = SwapEffect.Discard;
present.Windowed = true;
present.BackBufferHeight = form.ClientSize.Height;
present.BackBufferWidth = form.ClientSize.Width;
//present.BackBufferFormat = Format.Unknown;
device = new Device(new Direct3D(), 0, DeviceType.Hardware, form.Handle, CreateFlags.HardwareVertexProcessing, present);
vertices = new VertexBuffer(device, 3 * 20, Usage.WriteOnly, VertexFormat.None, Pool.Managed);
vertices.Lock(0, 0, LockFlags.None).WriteRange(new Vertex[]
{
new Vertex() { Color = Color.Red.ToArgb(), Position = new Vector4(400.0f, 100.0f, 0.5f, 1.0f) },
new Vertex() { Color = Color.Blue.ToArgb(), Position = new Vector4(650.0f, 500.0f, 0.5f, 1.0f) },
new Vertex() { Color = Color.Green.ToArgb(), Position = new Vector4(150.0f, 500.0f, 0.5f, 1.0f) }
});
vertices.Unlock();
// specifies the layout of the vertexes
vertexElems = new VertexElement[]
{
new VertexElement(0, 0, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.PositionTransformed, 0),
new VertexElement(0, 16, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),
VertexElement.VertexDeclarationEnd
};
vertexDecl = new VertexDeclaration(device, vertexElems);
}
}
}
You're going way above and beyond what you need to do when the window is resized. You're releasing every single DirectX object you've created, including the graphics device, and then recreating everything. This is going to take a comparatively long time, which is why you're seeing performance issues.
In fact, none of your objects need to be released. Simply call the Reset() function on the device to recreate the backbuffer to match the new window size. Check out some of the native Direct3D9 tutorials on window resizing to see how in general how the process works.

Transition of images in Windows Forms Picture box

I'm new to Windows Forms, in my project, i need to change the image in the picture box at runtime. I'm able to do that with the help of a timer. The picture just gets changed. Is it possible to do some transitions when image changes, for example fade in, fade out, blur etc.. If possible could some one please let me know how to do it. I searched in net but in vain.Thanks in advance.
Varun
Simply take new code file and paste below code in it
an original answer for the similar question, answer taken from another question
Answer
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
public class BlendPanel : Panel
{
private Image mImg1;
private Image mImg2;
private float mBlend;
public BlendPanel()
{
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
}
public Image Image1
{
get { return mImg1; }
set { mImg1 = value; Invalidate(); }
}
public Image Image2
{
get { return mImg2; }
set { mImg2 = value; Invalidate(); }
}
public float Blend
{
get { return mBlend; }
set { mBlend = value; Invalidate(); }
}
protected override void OnPaint(PaintEventArgs e)
{
if (mImg1 == null || mImg2 == null)
e.Graphics.FillRectangle(new SolidBrush(this.BackColor), new Rectangle(0, 0, this.Width, this.Height));
else
{
Rectangle rc = new Rectangle(0, 0, this.Width, this.Height);
ColorMatrix cm = new ColorMatrix();
ImageAttributes ia = new ImageAttributes();
cm.Matrix33 = mBlend;
ia.SetColorMatrix(cm);
e.Graphics.DrawImage(mImg2, rc, 0, 0, mImg2.Width, mImg2.Height, GraphicsUnit.Pixel, ia);
cm.Matrix33 = 1F - mBlend;
ia.SetColorMatrix(cm);
e.Graphics.DrawImage(mImg1, rc, 0, 0, mImg1.Width, mImg1.Height, GraphicsUnit.Pixel, ia);
}
base.OnPaint(e);
}
}
Build your project. You can now drop a BlendPanel from the top of the toolbox onto your form. Here's a sample program that uses it:
private float mBlend;
private int mDir = 1;
public int count = 0;
public Bitmap[] pictures;
public void myPhoto()
{
pictures = new Bitmap[9];
pictures[0] = new Bitmap(#"Library Images\cf3.jpg");
pictures[1] = new Bitmap(#"Library Images\cf4.jpg");
pictures[2] = new Bitmap(#"Library Images\l1.JPG");
pictures[3] = new Bitmap(#"Library Images\l2.JPG");
pictures[4] = new Bitmap(#"Library Images\l3.JPG");
pictures[5] = new Bitmap(#"Library Images\l4.JPG");
pictures[6] = new Bitmap(#"Library Images\l5.JPG");
pictures[7] = new Bitmap(#"Library Images\l6.JPG");
pictures[8] = new Bitmap(#"Library Images\l7.JPG");
timer1.Interval = 50; //time of transition
timer1.Tick += BlendTick;
try
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[++count];
}
catch
{
}
timer1.Enabled = true;
}
private void BlendTick(object sender, EventArgs e)
{
mBlend += mDir * 0.02F;
if (mBlend > 1)
{
mBlend = 0.0F;
if ((count + 1) < pictures.Length)
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[++count];
}
else
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[0];
count = 0;
}
}
blendPanel1.Blend = mBlend;
}
You'll need to modify the new Bitmap(#"yourimagePath"); calls. Build and run. You should see the displayed image smoothly morph from your first image to your second image without any flickering.
I hope it helps for other...
There is no built-in support for such effects, but you can implement them. I'd suggest to write a custom control that renders the image and have a method for fade-swap, fade itself can be reached with alpha-blending drawing with .NET Graphics class.
However, Graphics class isn't very fast, I don't recommend to use this technique for big images. If you need some fancy UI with hw-accelerated effects, take a look at WPF.
Blend effects are easy to get going by using the ColorMatrix class. There's a good example available in my answer in this thread.
A simple way to get a blur is to resize the image, making it smaller, then redraw it back, making it larger. The Graphics.InterpolationMode property affects the type of blur you'll get.
Those are quicky do-it-yourself solutions. Any decent graphics library has these kind of operations built-in. You probably want something free, check out ImageMagick.NET
To put it simply, not without external (3rd-party) libraries.

Resources