fileDialogue Bitmaps - c#

I would like to do some image processing in C# and need to align two images before applying a filter to them. I will attempt to do this by scanning the images at a fixed point in a small rectangular section, which I believe makes it necessary to use the Bitmap class.
This section has a large amount of white pixels so I would like to take an average pixel value in this area to find the shift in the y-axis, as there is a large white horizontal bar going across the images.
The x-axis will be the same in both images. I would like to setup a few test images with different shift values, from small to large, positive and negative, so I can search for the minimum value .
This will require a scroll bar on the images to move them in small amounts.
I am totally new to C#, and low level programmer. I have been trying to get the image in pictureBox1 with the following code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing.Imaging;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace imageAlign
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Bitmap myImage = (Bitmap)pictureBox1.Image;
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) ;
{
pictureBox1.Image = Image.FromFile();
// this.pictureBox1.Image = myImage;
}
}
}
}
I have left the Image.FromFile(); with nothing passed as I wish to choose the images when I click the button on the form. Currently, I only have one button and picture box.

You need to use the FileName property of the OpenFileDialog:
if (ofd.ShowDialog() == DialogResult.OK && ofd.FileName != "")
{
pictureBox1.Image = Image.FromFile(ofd.FileName);
}
From the link:
The file name includes both the file path and the extension. If no files are selected, this method returns an empty string ("").

Related

New form is not reporting its size as I expect

Continue from the overlay window's incorrect size problem.
So here is the minimum system:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.Size = new Size(1920, 1080);
MessageBox.Show("x:" + this.Size.Width + " y:" + this.Size.Height);
}
}
}
It says my window size is 1438x818 (even though it does appear to fill the desktop area of the screen)....
Did some new research
The problem starts to occur when my size is set larger than 14xx by 83x
Any size larger than that will be restricted to 14xx by 83x
if I say
this.size = new Size (500,500);
then it is okay...
[Final edit]
Well. I think I found the problem.
https://social.msdn.microsoft.com/Forums/vstudio/en-US/60e3b413-7746-46d4-8351-0c7f4e38378f/does-form-size-has-any-limitation-like-maximum-width-or-maximum-height?forum=netfxbcl
The form size does have a hidden limit and it seems that fixing it is out of my ability as an indie developer. I cannot find where is a hidden limitation is..
What I need to do is map the logic coordinate of anything in my form to a new world coordinate based on 1436/1920 scale ratio. Problem bypassed.
If you want to set size as 1920x1080 you can try this.
this.MinimumSize = new Size(1920, 1080);
this.MaximumSize = new Size(1920, 1080);
The size of the form must be lesser than or equal to current screen size.
Besides you can change the ClientSize of the form by
this.ClientSize = new System.Drawing.Size(1920, 1080);

How to render an image on the screen C#

I have been trying to create a test program that just displays a bitmap image on the screen for a while now. Ideally, the image would be translucent (have an alpha channel) and "click throughable." However, I have not found any way to do this.
The application that I have for this is a keyboard indicators app that runs in the background and displays a popup image onscreen for a couple seconds whenever a modifier like num lock or caps lock is pressed.
What I have found is an MSDN example for how to render an image on the screen, but I haven't been able to make this work properly in a Windows Forms app. In the Form1.cs of a blank WFA app, I have:
using System.Drawing;
using System.Windows.Forms;
namespace KeyboardIndicators
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
PictureBox pictureBox1 = new PictureBox();
pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
}
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs pe)
{
Bitmap myBitmap = new Bitmap("Profile Image.jpg");
Graphics g = pe.Graphics;
g.DrawImage(myBitmap, 100, 100);
}
}
}
I am probably missing a lot here, but I am not having much luck debugging it in Visual Studio.
I have yet to find a site online that fully describes how to do something like what I would like to do. I have seen this kind of thing done before in other apps, so I know it can be done somehow.
I found the answer to my question thanks to the initial answer by #Habeeb on this question, which inspired me to research that method. By looking at this Q/A, I realized I didn't need to create a helper function to do this. To #Idle_Mind's point also, I set the WS_EX_TRANSPARENT flag to transparent.
This is the code I ended up with in my Form1.cs file: (I ended up changing the test image to cube.png, a .png image with an alpha channel)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace KeyboardIndicators {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
PictureBox pictureBox = new PictureBox();
Image myBitmap = Image.FromFile("cube.png");
Size bitmapSize = new Size(myBitmap.Width, myBitmap.Height);
this.Size = bitmapSize;
pictureBox.ClientSize = bitmapSize;
pictureBox.Image = myBitmap;
pictureBox.Dock = DockStyle.Fill;
this.Controls.Add(pictureBox);
this.FormBorderStyle = FormBorderStyle.None;
}
protected override CreateParams CreateParams {
get {
CreateParams createParams = base.CreateParams;
createParams.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
return createParams;
}
}
}
}
When run, the following is shown onscreen:
This works for me, as it is overlayed on all apps I need, is semi-transparent and is click-throughable.
From your code, I do not see the Bitmap image is set to the PictureBox.
Please try the below code:
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage ;
MyImage = new Bitmap(fileToDisplay);
pictureBox1.ClientSize = new Size(xSize, ySize);
pictureBox1.Image = (Image) MyImage ;
If you want to add PictureBox via code, see below:
private void Form1_Load(object sender, EventArgs e)
{
var picture = new PictureBox
{
Name = "pictureBox1",
Size = new Size(xSize, ySize),
Location = new Point(100, 100),
Image = Image.FromFile("hello.jpg"),
};
this.Controls.Add(picture);
}
The first piece of code shows how to update image, but a different approach.

Capture screen shot as video and display live but mirrored?

I'm trying to develop a c# windows form application that captures part of the screen and display it's mirror live video like in the windows form picturebox.
The problem that I'm facing is that when I set the form's visibility=false to capture part of the screen without capturing the form itself, then back to form visibility=true, I get this flickering mirrored and not mirrored picture displaying in the picturebox.
My issue is that I'm trying to mirror any video playing on what ever application i.e: youtube, windows media player or any other application by capturing multiple screenshots and displaying them in a picture box so that when the video is playing and the application is running in front of it, the user see's a mirror of whatever is playing behind the form live.
How do I stop the flickering and make this like video like live stream like of the back video but mirrored as the video is playing. Thank you in advance
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Mirror
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
#region Form Design and Controls
private void btnFlip_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
Bitmap myBitmap = new Bitmap(this.Size.Width, this.Size.Height);
this.Visible = false;
using (Graphics g = Graphics.FromImage(myBitmap))
{
g.CopyFromScreen(0, 0, 0, 0, myBitmap.Size, CopyPixelOperation.SourceCopy);
}
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
this.pictureBox1.Image = myBitmap;
pictureBox1.Image.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipY);
GC.Collect();
}
this.Visible = true;
}
#endregion
}
}

How can I show Kinect video stream in Windows.Forms.PictureBox appropriately?

I'm trying to display Kinect's video stream into PictureBox. The reason is, I'd like to overlay it with some images and use FillEllipse() method to add real time markers.
However, I ended up with a box with a red x (cross) in it. Could someone show me, where did I go wrong? Should I use WritableBitmap instead? I had a thought of this, but Writeable bitmap does not offer method such as FillEllipse() to place markers.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Kinect;
using System.Drawing.Imaging;
using System.Drawing;
using System.Runtime.InteropServices;
namespace fTrack_WF
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
KinectSensor myKinect;
private void Window_Loaded(object sender, EventArgs e)
{
if (KinectSensor.KinectSensors.Count == 0)
{
MessageBox.Show("No Kinects device detected", "Camera View");
Application.Exit();
return;
}
try
{
// get first Kinect device attached on computer
myKinect = KinectSensor.KinectSensors[0];
// enable depth stream
myKinect.DepthStream.Enable();
// enable color video stream
myKinect.ColorStream.Enable();
// start the sensor
myKinect.Start();
// connect up the video event handler
myKinect.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(myKinect_ColorFrameReady);
}
catch
{
MessageBox.Show("Kinect initialise failed", "Camera viewer");
Application.Exit();
}
}
#region Video Image Processing
byte[] colorData = null;
Bitmap kinectVideoBitmap = null;
IntPtr colorPtr;
void myKinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
{
if (colorFrame == null) return;
if (colorData == null)
colorData = new byte[colorFrame.PixelDataLength];
colorFrame.CopyPixelDataTo(colorData);
Marshal.FreeHGlobal(colorPtr);
colorPtr = Marshal.AllocHGlobal(colorData.Length);
Marshal.Copy(colorData, 0, colorPtr, colorData.Length);
kinectVideoBitmap = new Bitmap(
colorFrame.Width,
colorFrame.Height,
colorFrame.Width * colorFrame.BytesPerPixel;
PixelFormat.Format32bppRgb,
colorPtr);
kinectVideoBox.Image = kinectVideoBitmap;
kinectVideoBitmap.Dispose();
}
}
#endregion
}
}
Thank you very much!
Regards,
ikel
I'm not clear why you are using a WinForms PictureBox over just using WPF.
Have you tried placing a Canvas on top of the video stream, demonstrated in the SDK examples, and simply drawn to that?
<Grid HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="320" Height="240">
<lt:KinectDepthViewer x:Name="DepthViewer" KinectSensorManager="{Binding KinectSensorManager}" />
<Canvas>
<lt:KinectSkeletonViewer
KinectSensorManager="{Binding KinectSensorManager}"
Width="{Binding ElementName=DepthViewer, Path=ActualWidth}"
Height="{Binding ElementName=DepthViewer, Path=ActualHeight}"
ShowBones="True" ShowJoints="True" ShowCenter="True" ImageType="Depth" />
</Canvas>
</Grid>
<Canvas Name="DrawingCanvas">
</Canvas>
The second canvas is at a higher z-index and any object on that will cover up your video stream.
P.S.
Although my code points to the depth viewer, the video stream is done in the same way when using the examples from the SDK.
I found the answer. Dispose is necessary to free up resources as indicated here. The problem was, I disposed too early after drawing it, and so it appeared as if nothing was drawn. However, the clearer answer, to me anyway, was given here.
Bitmap inherits from Image, which implements IDisposable, so when
you're done using an instance, you should call Dispose() on it. This
will clean up the unmanaged resource in Image.
However, Image also implements a finalizer, so if for some reason you
cannot call Dispose(), the resource will be reclaimed during
finalization of the instance, which will happen at some point after
the instance is no longer referenced.
I simply removed kinectVideoBitmap.Dispose(); and my Windows Forms displays Kinect's video stream inside PictureBox control.
Regards,
ikel

C# - Detect face and crop image

I'm writing a HttpHandler in C# which serves resized images and blah blah blah... No troubles, we have millions of handlers to use as reference.
The problem is that I have pictures of my users taken with "traditional" sizes, as 4:3 and 16:9. But this handler will need to serve the picture in a Photo ID size (4cm by 3cm) and obviously has need of cropping around the user face. The faces positions vary a lot (aren't always at the picture center).
So, what kind of algorithm I could use to detect the face center and then crop the image around this point?
You can use HaarCascade class in EmguCV (DotNet port of OpenCV) http://www.emgu.com/wiki/index.php/Face_detection
Notes in order to run this example:
Create a Windows Form Application
Add a PictureBox and a Timer (and Enable it) - Run it on a x86 system
Be sure you have the OpenCV relevant dlls (included with the Emgu CV download) in the folder where you code executes.
Adjust the path to find the Haarcascade xml (last line of the code)
using System;
using System.Windows.Forms;
using System.Drawing;
using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
namespace opencvtut
{
public partial class Form1 : Form
{
private Capture cap;
private HaarCascade haar;
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
using (Image<Bgr, byte> nextFrame = cap.QueryFrame())
{
if (nextFrame != null)
{
// there's only one channel (greyscale), hence the zero index
//var faces = nextFrame.DetectHaarCascade(haar)[0];
Image<Gray, byte> grayframe = nextFrame.Convert<Gray, byte>();
var faces =
grayframe.DetectHaarCascade(
haar, 1.4, 4,
HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
new Size(nextFrame.Width/8, nextFrame.Height/8)
)[0];
foreach (var face in faces)
{
nextFrame.Draw(face.rect, new Bgr(0,double.MaxValue,0), 3);
}
pictureBox1.Image = nextFrame.ToBitmap();
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
// passing 0 gets zeroth webcam
cap = new Capture(0);
// adjust path to find your xml
haar = new HaarCascade(
"..\\..\\..\\..\\lib\\haarcascade_frontalface_alt2.xml");
}
}
}
If you are looking for cropping your image, you could use the Microsoft Cognitive Service named Face API which delimiters the face of all persons on your photo, it gives you back a JSON which has the elements to return you a Rectangle struct, then you can Crop and Resize your image as you want.
Here you can see more informationa about it: FaceAPI
You can see an example of face detection and cropping software at http://deteksiwajah.blogspot.com/. It is open source and using OpenCV library.

Categories