/* Code revised from chapter 6 GDI+ Custom Controls with Visual C# 2005 By Iulian Serban, Dragos Brezoi, Tiberiu Radu, Adam Ward Language English Paperback 272 pages [191mm x 235mm] Release date July 2006 ISBN 1904811604 Sample chapter http://international.us.server12.fileserver.kutayzorlu.com/files/download/2017/01/1604_CustomControls_SampleChapter_uuid-4b87262d-deb6-49f2-8cc3-13c5abbb3ded_crc-0.pdf For More info on GDI+ Custom Control with Microsoft Visual C# book visit website www.packtpub.com */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace ImageWarperApp { public partial class Form1 : Form { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } public Form1() { InitializeComponent(); } private void applyButton_Click(object sender, EventArgs e) { imageWarperControl1.ImageAngle = Double.Parse(angleBox.Text) * System.Math.PI / 180; imageWarperControl1.ImageScale = Double.Parse(scaleBox.Text) / 100; imageWarperControl1.ImageSkew = new SizeF(float.Parse(skewHorizontalBox.Text), float.Parse(skewVerticalBox.Text)); } private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.angleBox = new System.Windows.Forms.TextBox(); this.scaleBox = new System.Windows.Forms.TextBox(); this.skewHorizontalBox = new System.Windows.Forms.TextBox(); this.skewVerticalBox = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label(); this.applyButton = new System.Windows.Forms.Button(); this.imageWarperControl1 = new ImageWarperApp.ImageWarperControl(); this.SuspendLayout(); // // angleBox // this.angleBox.Location = new System.Drawing.Point(128, 42); this.angleBox.Name = "angleBox"; this.angleBox.Size = new System.Drawing.Size(100, 20); this.angleBox.TabIndex = 1; // // scaleBox // this.scaleBox.Location = new System.Drawing.Point(128, 100); this.scaleBox.Name = "scaleBox"; this.scaleBox.Size = new System.Drawing.Size(100, 20); this.scaleBox.TabIndex = 2; // // skewHorizontalBox // this.skewHorizontalBox.Location = new System.Drawing.Point(128, 157); this.skewHorizontalBox.Name = "skewHorizontalBox"; this.skewHorizontalBox.Size = new System.Drawing.Size(100, 20); this.skewHorizontalBox.TabIndex = 3; // // skewVerticalBox // this.skewVerticalBox.Location = new System.Drawing.Point(128, 217); this.skewVerticalBox.Name = "skewVerticalBox"; this.skewVerticalBox.Size = new System.Drawing.Size(100, 20); this.skewVerticalBox.TabIndex = 4; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(7, 45); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(104, 13); this.label1.TabIndex = 5; this.label1.Text = "Rotation Angle (deg)"; // // label2 // this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(7, 103); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(84, 13); this.label2.TabIndex = 6; this.label2.Text = "Scale Factor (%)"; // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(7, 160); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(117, 13); this.label3.TabIndex = 7; this.label3.Text = "Skew Horizontal Factor"; // // label4 // this.label4.AutoSize = true; this.label4.Location = new System.Drawing.Point(7, 220); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(105, 13); this.label4.TabIndex = 8; this.label4.Text = "Skew Vertical Factor"; // // applyButton // this.applyButton.BackColor = System.Drawing.SystemColors.ActiveCaption; this.applyButton.Location = new System.Drawing.Point(61, 285); this.applyButton.Name = "applyButton"; this.applyButton.Size = new System.Drawing.Size(118, 34); this.applyButton.TabIndex = 9; this.applyButton.Text = "Apply New Settings"; this.applyButton.UseVisualStyleBackColor = false; this.applyButton.Click += new System.EventHandler(this.applyButton_Click); // // imageWarperControl1 // this.imageWarperControl1.ImageAngle = 0; this.imageWarperControl1.ImageScale = 0; this.imageWarperControl1.ImageSkew = new System.Drawing.SizeF(0F, 0F); this.imageWarperControl1.Location = new System.Drawing.Point(253, 45); this.imageWarperControl1.Name = "imageWarperControl1"; this.imageWarperControl1.Size = new System.Drawing.Size(185, 192); this.imageWarperControl1.TabIndex = 0; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(450, 342); this.Controls.Add(this.applyButton); this.Controls.Add(this.label4); this.Controls.Add(this.label3); this.Controls.Add(this.label2); this.Controls.Add(this.label1); this.Controls.Add(this.skewVerticalBox); this.Controls.Add(this.skewHorizontalBox); this.Controls.Add(this.scaleBox); this.Controls.Add(this.angleBox); this.Controls.Add(this.imageWarperControl1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); this.PerformLayout(); } #endregion private ImageWarperControl imageWarperControl1; private System.Windows.Forms.TextBox angleBox; private System.Windows.Forms.TextBox scaleBox; private System.Windows.Forms.TextBox skewHorizontalBox; private System.Windows.Forms.TextBox skewVerticalBox; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label3; private System.Windows.Forms.Label label4; private System.Windows.Forms.Button applyButton; } public partial class ImageWarperControl : UserControl { public ImageWarperControl() { InitializeComponent(); } private void ImageWarperControl_Load(object sender, EventArgs e) { img = CreatePicture(); } private void ImageWarperControl_Paint(object sender, PaintEventArgs e) { // set up all our parameters first before calling DrawWarpedPicture. Graphics target = this.CreateGraphics(); //draw onto the form's surface PointF pivotOnImage = new PointF(img.Width / 2, img.Height / 2); PointF pivotOnTarget = new PointF(this.Width / 2, this.Height / 2); double rotate = imageAngle; double scaleFactor = imageScale; SizeF skewing = imageSkew; DrawWarpedPicture(target, img, pivotOnImage, pivotOnTarget, rotate, scaleFactor, skewing); } private Image CreatePicture() { // Create a new Bitmap object, 50 x 50 pixels in size Image canvas = new Bitmap(50, 50); // create an object that will do the drawing operations Graphics artist = Graphics.FromImage(canvas); // draw a few shapes on the canvas picture artist.Clear(Color.Lime); artist.FillEllipse(Brushes.Red, 3, 30, 30, 30); artist.DrawBezier(new Pen(Color.Blue, 3), 0, 0, 40, 15, 10, 35, 50, 50); // now the drawing is done, we can discard the artist object artist.Dispose(); // return the picture return canvas; } public void DrawWarpedPicture( Graphics surface, //the surface to draw on Image img, //the image to draw PointF sourceAxle, //pivot point passing through image. PointF destAxle, //pivot point's position on destination surface double degrees, //degrees through which the image is rotated clockwise double scale, //size multiplier SizeF skew //the slanting effect size, applies BEFORE scaling or rotation ) { //give this array temporary coords that will be overwritten in the loop below //the skewing is done here orthogonally, before any trigonometry is applied PointF[] temp = new PointF[3] { new PointF(skew.Width, -skew.Height), new PointF((img.Width - 1) + skew.Width, skew.Height), new PointF(-skew.Width,(img.Height - 1) - skew.Height) }; double ang, dist; //convert the images corner points into scaled, rotated, skewed and translated points for (int i = 0; i < 3; i++) { //measure the angle to the image's corner and then add the rotation value to it ang = GetBearingRadians(sourceAxle, temp[i], out dist) + degrees; dist *= scale; //scale temp[i] = new PointF((Single)((Math.Cos(ang) * dist) + destAxle.X), (Single)((Math.Sin(ang) * dist) + destAxle.Y)); } surface.DrawImage(img, temp); } private static double GetBearingRadians(PointF reference, PointF target, out double distance) { double dx = target.X - reference.X; double dy = target.Y - reference.Y; double result = Math.Atan2(dy, dx); distance = Math.Sqrt((dx * dx) + (dy * dy)); if (result < 0) result += (Math.PI * 2); //add the negative number to 360 degrees to correct the atan2 value return result; } private double imageAngle; private double imageScale; private SizeF imageSkew; private Image img = null; public double ImageAngle { get { return imageAngle; } set { if (imageAngle != value) { imageAngle = value; Invalidate(); } } } public double ImageScale { get { return imageScale; } set { if (imageScale != value) { imageScale = value; Invalidate(); } } } public SizeF ImageSkew { get { return imageSkew; } set { if (imageSkew != value) { imageSkew = value; Invalidate(); } } } private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.SuspendLayout(); // // ImageWarperControl // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Name = "ImageWarperControl"; this.Load += new System.EventHandler(this.ImageWarperControl_Load); this.Paint += new System.Windows.Forms.PaintEventHandler(this.ImageWarperControl_Paint); this.ResumeLayout(false); } #endregion } }