Click here to Skip to main content
15,885,309 members
Articles / Game Development

Cutting Edge - Motion, Texture And 3D Forms As Interactive Services (Part I)

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
8 Sep 2012MIT7 min read 26.8K   898   12  
This article is the first toddler step in the development of a framework for the delivery of motion, touch and 3D forms as interactive services locally and over networks.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Drawing.Imaging;

using KC36.Interop;

namespace KC36.Client
{
    public unsafe partial class ClientMainUI : Form
    {
        private static bool isInitialised = false;
        private static int DirectionToDisplay = -1;
        private int Stride = 0;
        private int BitsPerPixel = 0;
        private static int PixelArrayCount = 0;
        private static int* Indices;
        private static int* EdgeMetrics;
        private static int[] EdgeMetricsDecoded;
        private static byte[] EdgeMetricsArray;
        private ToolTip toolTip = new ToolTip();

        public ClientMainUI()
        {
            InitializeComponent();

            lblColorKey.Visible = false;
            picBoxColorKey.Visible = false;

            trkBarMinBrightnessDiffTolerance.Value = 177;
            lblMinBrightnessDiffTolerance.Text = trkBarMinBrightnessDiffTolerance.Value.ToString();
            picBoxPreview.SizeMode = PictureBoxSizeMode.Zoom;
            picBoxOutput.SizeMode = PictureBoxSizeMode.Zoom;
            picBoxEdgeMetrics.SizeMode = PictureBoxSizeMode.Zoom;
            Tools.PopulateDirectionList(cmbDirections);
            string[] pathBits = Application.StartupPath.Split('\\');
            string pathRoot = String.Empty;
            for (int i = 0; i < pathBits.Length - 1; i++)
            {
                if (pathBits[i].ToUpper() == "BIN")
                    break;
                pathRoot += pathBits[i] + "\\";
            }
            string defaultImagePath = pathRoot + "Splash.jpg";
            if (File.Exists(defaultImagePath))
            {
                picBoxPreview.Image = Image.FromFile(defaultImagePath);
                lblWidth.Text = picBoxPreview.Image.Width.ToString() + " px";
                lblHeight.Text = picBoxPreview.Image.Height.ToString() + " px";
            }
        }

        private void btnProcess_Click(object sender, EventArgs e)
        {
            picBoxOutput.Image = picBoxPreview.Image;
            Execute();  
        }

        private void btnLoadImage_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "JPEG Files (*.jpg)|*.jpg|PNG Files (*.png)|*.png";
            openFileDialog.Title = "Select an image to open";

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                picBoxPreview.Image = Image.FromFile(openFileDialog.FileName);
                lblWidth.Text = picBoxPreview.Image.Width.ToString() + " px";
                lblHeight.Text = picBoxPreview.Image.Height.ToString() + " px";
            }
            isInitialised = false;
        }

        private void cmbDirections_SelectedIndexChanged(object sender, EventArgs e)
        {
            int x = Convert.ToInt32(((KeyValuePair<string, int>)cmbDirections.SelectedItem).Value);
            DirectionToDisplay = x;
            Execute();
        }

        private void cmbEdgeAngleTolerance_SelectedIndexChanged(object sender, EventArgs e)
        {
            isInitialised = false;
            Execute();
        }

        private void trkBarMinBrightnessDiffTolerance_Scroll(object sender, EventArgs e)
        {
            isInitialised = false;
            lblMinBrightnessDiffTolerance.Text = trkBarMinBrightnessDiffTolerance.Value.ToString();
        }

        private void tabCntrlOutput_SelectedIndexChanged(Object sender, EventArgs e)
        {
            lblColorKey.Visible = false;
            picBoxColorKey.Visible = false;
            TabPage tabpage = ((TabControl)(sender)).SelectedTab;
            if (tabpage.Text == "Polylines")
            {
                DrawSegments();
            }
            if (tabpage.Text == "Edge Metrics")
            {
                lblColorKey.Visible = true;
                picBoxColorKey.Visible = true;
            }
        }

        private unsafe void picBoxEdgeMetrics_MouseDown(object sender, MouseEventArgs e)
        {
            Image image = picBoxEdgeMetrics.Image;
            if (null != image)
            {
                Point p = picBoxEdgeMetrics.MousePositionOnImage;
                int x = p.X;
                int y = p.Y;
                int index = (y * (int)image.Width * BitsPerPixel) + (x * BitsPerPixel);
                int metric = EdgeMetricsDecoded[index];
                string display = String.Empty;
                display = metric.ToString();
                display += " (" + x.ToString() + ", " + y.ToString() + ")";
                toolTip.Show(display, picBoxEdgeMetrics, new Point(10, 10));
            }            
        }
        
        private unsafe void Execute()
        {
            BitsPerPixel = 4;//this should come in as a parameter or property from the image source.
            Bitmap bitmap = (Bitmap)picBoxPreview.Image;
            byte[] pixelArray = Tools.GetBytes(bitmap);
            PixelArrayCount = pixelArray.Length;
            Stride = bitmap.Width * BitsPerPixel;
            int width = bitmap.Width;
            int height = bitmap.Height;

            if (!isInitialised)
            {
                if (cmbEdgeAngleTolerance.SelectedIndex < 0)
                    Wrapper.InitialiseCore(width, height, Stride, trkBarMinBrightnessDiffTolerance.Value, 1);
                else
                    Wrapper.InitialiseCore(width, height, Stride, trkBarMinBrightnessDiffTolerance.Value, Convert.ToInt32(cmbEdgeAngleTolerance.SelectedItem));
                isInitialised = true;
            }

            Stopwatch watch = new Stopwatch();
            watch.Start();

            Wrapper.GetFeaturedList(pixelArray);
            int* directions = Wrapper.Directions;
            Indices = Wrapper.DirectionIndices;
            EdgeMetrics = Wrapper.EdgeMetrics;
            int featurePointCount = Wrapper.FeaturePointCount;

            watch.Stop();
            lblElapsedtime.Text = watch.ElapsedMilliseconds.ToString();
            lblFeatures.Text = featurePointCount.ToString();

            byte[] outlinedArray = Tools.OutlineFeatures(Indices, directions, pixelArray.Length, featurePointCount, DirectionToDisplay);
            Bitmap bitmap2 = Tools.GetBitmap(outlinedArray, Stride, width, height);
            picBoxOutput.Image = bitmap2;

            EdgeMetricsDecoded = Tools.GetEdgeMetrics(Indices, EdgeMetrics, width, height, BitsPerPixel, featurePointCount);
            EdgeMetricsArray = Tools.GetEdgeMetricsForDisplay(Indices, EdgeMetrics, pixelArray.Length, featurePointCount);
            Bitmap bitmap3 = Tools.GetBitmap(EdgeMetricsArray, Stride, width, height);
            picBoxEdgeMetrics.Image = bitmap3;
        }

        private unsafe void DrawSegments()
        {
            byte[] pixelArray = new byte[PixelArrayCount];
            int segmentPropertyCount = Wrapper.SegmentPropertyCount;
            int[] segments = new int[segmentPropertyCount];
            int* segmentsNative = Wrapper.SegmentProperties;
            for (int i = 0; i < segmentPropertyCount; i++)
            {
                segments[i] = segmentsNative[i];
            }
            if (segmentPropertyCount > 0)
            {
                Bitmap bitmap = new Bitmap(picBoxOutput.Image.Size.Width, picBoxOutput.Image.Size.Height);
                using (Graphics bitmapGraphics = Graphics.FromImage(bitmap))
                {
                    bool isAlternate = false;
                    bitmapGraphics.FillRectangle(Brushes.Black, new Rectangle(0, 0,
                        bitmap.Width, bitmap.Height));

                    Pen pen = new Pen(Color.Transparent, 2);
                    Point pointStart = new Point();
                    Point pointEnd = new Point();

                    // 0 index, 1 start x, 2 start y, 3 end x, 4 end y, 5 start depth, 6 end depth, 7 pixel count, 8 octant, 9 angle
                    for (int i = 0; i < segmentPropertyCount; )
                    {
                        pointStart.X = segments[i + 1];
                        pointStart.Y = segments[i + 2];
                        pointEnd.X = segments[i + 3];
                        pointEnd.Y = segments[i + 4];
                        
                        if (isAlternate)
                            pen.Color = Color.Orange;
                        else
                            pen.Color = Color.Cyan;

                        bitmapGraphics.DrawLine(pen, pointStart, pointEnd);

                        isAlternate = !isAlternate;
                        i += 10;
                    }
                }
                picBoxPolyline.Image = bitmap;
                picBoxPolyline.Size = picBoxOutput.Size;
                picBoxPolyline.SizeMode = PictureBoxSizeMode.Zoom;

            }
        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Web Developer
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions