Affecting Streamsource from a bitmap to another not working - c#

Rotating a bitmapImage using UriSource works using the following code
private void RotateDocumentImageSourceRight()
{
var biOriginal = (BitmapImage)documentImage.Source;
if (biOriginal == null)
return;
var biRotated = new BitmapImage();
biRotated.BeginInit();
biRotated.UriSource = biOriginal.UriSource;
switch (biOriginal.Rotation)
{
case Rotation.Rotate0:
biRotated.Rotation = Rotation.Rotate270;
break;
case Rotation.Rotate270:
biRotated.Rotation = Rotation.Rotate180;
break;
case Rotation.Rotate180:
biRotated.Rotation = Rotation.Rotate90;
break;
case Rotation.Rotate90:
biRotated.Rotation = Rotation.Rotate0;
break;
default:
break;
}
biRotated.EndInit();
documentImage.Source = biRotated;
}
But when I change the way a bitmapImage is stored to StreamSource it doesn't work and the image disappears
private void RotateDocumentImageSourceRight()
{
...same code...
biRotated.StreamSource= biOriginal.StreamSource;
...same code...
}

You can use a TransformedBitmap, which is used by BitmapImage internally when you specify the Rotation property. It will create a new image, but it will be faster (it won't need to read the stream again).
private void RotateDocumentImageSourceRight()
{
var biOriginal = (BitmapSource)documentImage.Source;
if (biOriginal == null)
return;
var angle = 0.0;
var biRotated = biOriginal as TransformedBitmap;
if (biRotated != null)
{
biOriginal = biRotated.Source;
angle = ((RotateTransform)biRotated.Transform).Angle;
}
angle -= 90;
if (angle < 0) angle += 360;
biRotated = new TransformedBitmap(biOriginal, new RotateTransform(angle));
documentImage.Source = biRotated;
}

Related

Why getting exception The process cannot access the file image0.gif' because it is being used by another process even if I dispose it first?

private void GenerateAnimatedGifs()
{
UnFreezWrapper unfreezWrapper = new UnFreezWrapper();
checkBoxGetImages = false;
checkBoxGetAllImages.Checked = false;
GetImagesFiles();
for (int i = 0; i < filesSatellite.Length; i++)
{
Image img = Image.FromFile(filesSatellite[i]);
img.Save(filesSatellite[i] + "ConvertedToGif.gif", System.Drawing.Imaging.ImageFormat.Gif);
img.Dispose();
File.Delete(filesSatellite[i]);
}
GetImagesFiles();
unfreezWrapper.MakeGIF(filesRadar.ToList(), #"d:\Downloaded Images\Animates Gifs\radanim.gif", 100, true);
unfreezWrapper.MakeGIF(filesSatellite.ToList(), #"d:\Downloaded Images\Animates Gifs\satanim.gif", 100, true);
}
In the loop I convert each image to gif save it in other name and then dispose the original image and then trying to delete the original image so only the ConvertedToGif images will left.
but I'm getting the exception is being used by another process on the delete line
File.Delete(filesSatellite[i]);
but isn't the file disposed already ?
The problem is that in the constructor I'm loading the images to a pictureBox using timer that is why the images are busy with another process.
If I'm not loading the images at the constructor everything will work fine.
But I want to display the images when running the application and also to be able to convert them to other formats and making other manipulations like creating animated gif of them.
I'm stuck here.
This is the constructor code
public Form1()
{
InitializeComponent();
CheckIfImagesExist();
}
And the code of the CheckIfImagesExist method
private void CheckIfImagesExist()
{
GetImagesFiles();
if (filesRadar != null)
{
if (filesRadar.Length > 1)
{
pictureBox1.Image = new Bitmap(filesRadar[0]);
trackBar1.Enabled = true;
timer1.Enabled = true;
}
if (filesRadar.Length == 1)
{
trackBar1.Enabled = false;
pictureBox1.Image = new Bitmap(filesRadar[0]);
}
}
if (filesSatellite != null)
{
if (filesSatellite.Length > 1)
{
pictureBox2.Image = new Bitmap(filesSatellite[0]);
trackBar1.Enabled = true;
timer2.Enabled = true;
}
if (filesSatellite.Length == 1)
{
trackBar1.Enabled = false;
pictureBox2.Image = new Bitmap(filesSatellite[0]);
}
}
}
The timer tick event
int satImagesCount = 0;
private void timer2_Tick(object sender, EventArgs e)
{
satImagesCount++;
if (satImagesCount == filesSatellite.Length)
{
satImagesCount = 0;
}
pictureBox2.Image = new Bitmap(filesSatellite[satImagesCount]);
if (isInsideSat)
{
pb.Image = new Bitmap(filesSatellite[satImagesCount]);
timer2.Interval = trackBar1.Value * 100;
}
}

Hand tracking Kinect SDK 1.7

I want to detect hand state if it gripped or released using Kinect SDK v1.7 implemented with C#, but I'm tired from this an exception:
Exception thrown: 'System.InvalidOperationException' in
Microsoft.Kinect.Toolkit.Interaction.dll
The code:
private void InteractionStreamOnInteractionFrameReady(object sender,InteractionFrameReadyEventArgs e)
{
using (InteractionFrame frame = e.OpenInteractionFrame())
{
if (frame != null)
{
if (this.userInfos == null)
{
this.userInfos = new UserInfo[InteractionFrame.UserInfoArrayLength];
}
frame.CopyInteractionDataTo(this.userInfos);
}
else
{ return;}
}
foreach (UserInfo userInfo in this.userInfos)
{
foreach (InteractionHandPointer handPointer in userInfo.HandPointers)
{
string action = null;
switch (handPointer.HandEventType)
{
case InteractionHandEventType.Grip:
action = "gripped";
break;
case InteractionHandEventType.GripRelease:
action = "released";
break;
}
if (action != null)
{
string handSide = "unknown";
switch (handPointer.HandType)
{
case InteractionHandType.Left:
handSide = "left";
break;
case InteractionHandType.Right:
handSide = "right";
break;
}
if (handSide == "left")
{
if (action == "released")
{
// left hand released code here
//MessageBox.Show("left hand released");
System.Console.WriteLine("left hand released");
}
else
{
// left hand gripped code here
System.Console.WriteLine("left hand gripped");
}
}
else
{
if (action == "released")
{
// right hand released code here
System.Console.WriteLine("right hand released");
}
else
{
// right hand gripped code here
System.Console.WriteLine("right hand gripped");
}
}
}
}
}
}
private void WindowLoaded(object sender, RoutedEventArgs e)
{
// Create the drawing group we'll use for drawing
this.drawingGroup = new DrawingGroup();
// Create an image source that we can use in our image control
this.imageSource = new DrawingImage(this.drawingGroup);
// Display the drawing using our image control
Image.Source = this.imageSource;
sensor = KinectSensor.KinectSensors.FirstOrDefault();
if (null != this.sensor )
{
System.Console.WriteLine("Start streaming");
skeletons = new
Skeleton[sensor.SkeletonStream.FrameSkeletonArrayLength];
userInfos = new
UserInfo[InteractionFrame.UserInfoArrayLength];
this.sensor.SkeletonStream.Enable();
this.interactionStream = new InteractionStream(this.sensor,
new
DummyInteractionClient());
this.interactionStream.InteractionFrameReady +=
InteractionStreamOnInteractionFrameReady;
sensor.SkeletonFrameReady += SensorSkeletonFrameReady;
// Start the sensor !
try
{
this.sensor.Start();
}
catch (IOException)
{
//////// this.sensor = null;
}
}
if (null == this.sensor)
{
System.Console.WriteLine("NoKinectReady");
}
}

Leap Motion gets confused between different gesture types. How to optimize?

The swipe gestures Left,Right, Up and Down are not optimized. If a task has to be performed with an upward swipe, it would get confused with a left swipe and still perform it.Please suggest me the parameters to be optimized for differentiating swipes.Or commands for perfect swipe recognition
Also it gets confused with a circle and a swipe.
I have added my code. In one single frame only one gesture should be detected.How do i limit this here.
public MainWindow()
{
InitializeComponent();
this.controller = new Controller();
this.listener = new LeapListener(this);
controller.AddListener(listener);
for (int iCount = 1; iCount < 23; iCount++)
{
images[iCount] = new BitmapImage();
images[iCount].BeginInit();
images[iCount].UriSource = new Uri("Images/" + iCount + ".png", UriKind.Relative);
images[iCount].EndInit();
}
image.Source = images[1];
}
delegate void LeapEventDelegate(string EventName);
public void LeapEventNotification(string EventName)
{
if (this.CheckAccess())
{
switch (EventName)
{
case "onInit":
break;
case "onConnect":
this.connectHandler();
break;
case "onFrame":
this.checkGestures(this.controller.Frame());
break;
}
}
else
{
Dispatcher.Invoke(new LeapEventDelegate(LeapEventNotification
), new object[] { EventName });
}
}
public void connectHandler()
{
controller.EnableGesture(Gesture.GestureType.TYPE_SWIPE);
this.controller.EnableGesture(Gesture.GestureType.TYPE_CIRCLE);
this.controller.EnableGesture(Gesture.GestureType.TYPE_KEY_TAP);
this.controller.EnableGesture(Gesture.GestureType.TYPE_SCREEN_TAP);
// controller.Config.SetFloat("Gesture.Swipe.Speed", 4000.0f);
controller.Config.SetFloat("Gesture.Swipe.MinVelocity", 750f);
controller.Config.SetFloat("Gesture.Swipe.MinLength", 200f);
controller.Config.SetFloat("Gesture.KeyTap.MinDownVelocity", 40.0f);
controller.Config.SetFloat("Gesture.KeyTap.HistorySeconds", .2f);
controller.Config.SetFloat("Gesture.KeyTap.MinDistance", 40.0f);
controller.Config.SetFloat("Gesture.Circle.MinRadius", 15.0f);
controller.Config.SetFloat("Gesture.Circle.MinArc", 15f);
controller.Config.SetFloat("InteractionBox.Width", 1600.0f);
controller.Config.SetFloat("InteractionBox.Height", 1600.0f);
controller.Config.Save();
}
public void checkGestures(Frame frame)
{
GestureList gestures = frame.Gestures();
foreach (Gesture gesture in gestures)
{
// For Image 1
if (image.Source.Equals(images[1]))
{
if (gesture.Type == Gesture.GestureType.TYPE_SWIPE)
{
SwipeGesture swipe = new SwipeGesture(gesture);
if (swipe.State == Gesture.GestureState.STATE_START && swipe.Direction.x > 0 && Math.Abs(swipe.Direction.y) < 5)
{
image.Source = images[2];
// Console.WriteLine("Second");
}
}
}
// For Image 2
else if (image.Source.Equals(images[2]))
{
if (gesture.Type == Gesture.GestureType.TYPE_SWIPE)
{
SwipeGesture swipe = new SwipeGesture(gesture);
if (swipe.State == Gesture.GestureState.STATE_START && swipe.Direction.y > 0)
{
image.Source = images[3];
}
else if (swipe.State == Gesture.GestureState.STATE_START && swipe.Direction.x > 0 && Math.Abs(swipe.Direction.y) < 5)
{
image.Source = images[7];
}
}
if (gesture.Type == Gesture.GestureType.TYPE_KEY_TAP)
{
KeyTapGesture TapGesture = new KeyTapGesture(gesture);
image.Source = images[1];
Console.WriteLine("Circle");
}
}
// For Image 3
else if (image.Source.Equals(images[3]))
{
if (gesture.Type == Gesture.GestureType.TYPE_SWIPE)
{
SwipeGesture swipe = new SwipeGesture(gesture);
if (swipe.State == Gesture.GestureState.STATE_START && swipe.Direction.y < 0)
{
image.Source = images[4];
}
else if (swipe.State == Gesture.GestureState.STATE_START && swipe.Direction.x < 0 && Math.Abs(swipe.Direction.y) < 5)
{
image.Source = images[16];
}
}
if (gesture.Type == Gesture.GestureType.TYPE_KEY_TAP)
{
KeyTapGesture TapGesture = new KeyTapGesture(gesture);
image.Source = images[1];
}
}
}//foreach
}
}
}
The out of the box Gestures were deprecated in 3.x (Orion) as they weren't to reliable.
The best thing to do is to understand the SDK and just create your own gestures, you can go beyond whats already Out of the box and more reliable.
Everything its about 3d positioning so pay attention to your Y,X,Z, use the debuger hands or create your own debug system to see how it behaves.

Luxand API in Visual Studio 2010?

How can I use Luxand API to get to work in visual studio 2010? I need to detect points of chin in a given face, can I do it with any other API?
I have tried this sample code:
OpenFileDialog openFileDialog1 = new OpenFileDialog();
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
FSDK.CImage image = new FSDK.CImage(openFileDialog1.FileName);
// resize image to fit the window width
double ratio = System.Math.Min((pictureBox1.Width + 0.4) / image.Width,
(pictureBox1.Height + 0.4) / image.Height);
image = image.Resize(ratio);
Image frameImage = image.ToCLRImage();
Graphics gr = Graphics.FromImage(frameImage);
FSDK.TFacePosition facePosition = image.DetectFace();
if (0 == facePosition.w)
MessageBox.Show("No faces detected", "Face Detection");
else
{
int left = facePosition.xc - facePosition.w / 2;
int top = facePosition.yc - facePosition.w / 2;
gr.DrawRectangle(Pens.LightGreen, left, top, facePosition.w, facePosition.w);
FSDK.TPoint[] facialFeatures = image.DetectFacialFeaturesInRegion(ref facePosition);
int i = 0;
foreach (FSDK.TPoint point in facialFeatures)
gr.DrawEllipse((++i > 2) ? Pens.LightGreen : Pens.Blue, point.x, point.y, 3, 3);
gr.Flush();
}
// display image
pictureBox1.Image = frameImage;
pictureBox1.Refresh();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Exception");
}
}
I get this error:
Could not load file or assembly 'xquisite.application.exe' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.
what is your settings for your target? Any CPU ? Try x86 for Runtime !
have you add to your app.config <startup useLegacyV2RuntimeActivationPolicy="true"/>
?
These two thinks i forgot, were the reason of my errors which was the same as yours.
here is a piece of my code:
private void DetectFace()
{
var failerCounter = 0;
var cameraHandler = 0;
try
{
const int failerLimit = 2;
int failerLimitFaceDetection = Properties.Settings.Default.NotDetectedLimit;
float similarityMinimum = Properties.Settings.Default.SimilarityLimit;
var r = FSDKCam.OpenVideoCamera(ref CameraName, ref cameraHandler);
if (r != FSDK.FSDKE_OK)
{
MessageBox.Show(StringHelper.ErrorCamera);
}
FSDK.SetFaceDetectionParameters(
Properties.Settings.Default.DetectionHandleArbitaryRotations,
Properties.Settings.Default.DetectionDetermineFaceRotationAngle,
Properties.Settings.Default.DetectionInternalResizeWidth);
FSDK.SetFaceDetectionThreshold(Properties.Settings.Default.DetectionFaceDetectionThreshold);
while (IsFaceDetectionActive)
{
var imageHandle = 0;
if (FSDK.FSDKE_OK != FSDKCam.GrabFrame(cameraHandler, ref imageHandle))
{
Application.Current.Dispatcher.Invoke(delegate { }, DispatcherPriority.Background);
continue;
}
var image = new FSDK.CImage(imageHandle);
var frameImage = image.ToCLRImage();
FaceContent = frameImage;
var gr = Graphics.FromImage(frameImage);
var facePosition = image.DetectFace();
IsFaceDetected = facePosition.w != 0;
if (!IsFaceDetected)
{
if (failerCounter++ > failerLimitFaceDetection)
{
failerCounter = 0;
OnFaceNotDetected();
}
}
// if a face is detected, we detect facial features
if (IsFaceDetected)
{
var facialFeatures = image.DetectFacialFeaturesInRegion(ref facePosition);
SmoothFacialFeatures(ref facialFeatures);
FaceTemplate = image.GetFaceTemplate();
// Similarity = 0.5f -> fin the right value ....
IsFaceRecognized = FaceMetricHandler.LooksLike(FaceTemplate, similarityMinimum).Any();
if (IsFaceRecognized)
{
foreach (var match in FaceMetricHandler.LooksLike(FaceTemplate, similarityMinimum))
{
failerCounter = 0;
GreetingMessage = match.Name;
IsFaceDetectionActive = false;
OnFaceRecognized();
break;
}
}
else
{
if (failerCounter++ > failerLimit)
{
failerCounter = 0;
IsFaceDetectionActive = false;
OnFaceNotRecognized();
}
}
if (IsFaceFrameActive)
{
gr.DrawRectangle(Pens.Red, facePosition.xc - 2*facePosition.w/3,
facePosition.yc - facePosition.w/2,
4*facePosition.w/3, 4*facePosition.w/3);
}
}
else
{
ResetSmoothing();
}
FaceContent = frameImage;
GC.Collect();
Application.Current.Dispatcher.Invoke(delegate { }, DispatcherPriority.Background);
}
}
catch(Exception e)
{
logger.Fatal(e.Message);
InitializeCamera();
}
finally
{
FSDKCam.CloseVideoCamera(cameraHandler);
FSDKCam.FinalizeCapturing();
}
}
BTW, you can use x64 with win64\FaceSDK.NET.dll

Implementing the APNG Render Function

Hey everyone,
So, I'm currently trying the implement the APNG Specification, but am having some trouble with the frame rendering. My function is
private void UpdateUI()
{
foreach (PictureBox pb in pics)
{
APNGBox box = (APNGBox)pb.Tag;
APNGLib.APNG png = box.png;
if (box.buffer == null)
{
box.buffer = new Bitmap((int)png.Width, (int)png.Height);
}
APNGLib.Frame f = png.GetFrame(box.frameNum);
using (Graphics g = Graphics.FromImage(box.buffer))
{
switch (f.DisposeOp)
{
case APNGLib.Frame.DisposeOperation.NONE:
break;
case APNGLib.Frame.DisposeOperation.BACKGROUND:
g.Clear(Color.Transparent);
break;
case APNGLib.Frame.DisposeOperation.PREVIOUS:
if (box.prevBuffer != null)
{
g.DrawImage(box.prevBuffer, Point.Empty);
}
else
{
g.Clear(Color.Transparent);
}
break;
default:
break;
}
Bitmap read = png.ToBitmap(box.frameNum++);
switch (f.BlendOp)
{
case APNGLib.Frame.BlendOperation.OVER:
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
break;
case APNGLib.Frame.BlendOperation.SOURCE:
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
break;
default:
break;
}
g.DrawImage(read, new Point((int)f.XOffset, (int)f.YOffset));
}
box.prevBuffer = box.buffer;
pb.Image = box.buffer;
if (box.frameNum >= box.png.FrameCount)
{
box.frameNum = 0;
box.buffer = null;
box.prevBuffer = null;
}
}
}
The APNGBox is
internal class APNGBox
{
public int frameNum = 0;
public APNGLib.APNG png;
public Bitmap buffer;
public Bitmap prevBuffer;
}
I think that this is mostly correct, as I've run it against all the images in the APNG Gallery. However, some of them are rendering incorrectly (This one has artifacting issues, and this one does not retain the red bar on the left consistently). Please note, you'll have the view the page in Firefox 3 or higher to view the animations.
I'm lead to believe the issue has to do with how I handle the DISPOSE_OP_PREVIOUS, but I can't figure out what I'm doing wrong. Can anyone suggest what I might be missing?
So, I was able to figure it out in the end, and will post here in case anyone in the future comes across a similar problem. Turns out the issue was largely threefold:
One should not change the 'previous buffer' if the frame type is 'PREVIOUS'
One should use the previous frame's dispose_op, not the dispose_op of the current frame, to determine how it disposes
One should be sure to dispose only the old frame's region, not the whole frame
The new code is:
internal class APNGBox
{
public int frameNum { get; set; }
public APNGLib.APNG apng { get; set; }
public Bitmap buffer { get; set; }
public Bitmap prevBuffer { get; set; }
public APNGBox(APNGLib.APNG png)
{
frameNum = 0;
apng = png;
buffer = apng.ToBitmap(0);
prevBuffer = null;
}
}
private void UpdateUI()
{
foreach (PictureBox pb in pics)
{
APNGBox box = (APNGBox)pb.Tag;
APNGLib.APNG png = box.apng;
if (!png.IsAnimated)
{
if (pb.Image == null)
{
pb.Image = png.ToBitmap();
}
}
else
{
if (box.frameNum != png.FrameCount - 1)
{
Bitmap prev = box.prevBuffer == null ? null : new Bitmap(box.prevBuffer);
APNGLib.Frame f1 = png.GetFrame(box.frameNum);
if (f1.DisposeOp != APNGLib.Frame.DisposeOperation.PREVIOUS)
{
box.prevBuffer = new Bitmap(box.buffer);
}
DisposeBuffer(box.buffer, new Rectangle((int)f1.XOffset, (int)f1.YOffset, (int)f1.Width, (int)f1.Height), f1.DisposeOp, prev);
box.frameNum++;
APNGLib.Frame f2 = png.GetFrame(box.frameNum);
RenderNextFrame(box.buffer, new Point((int)f2.XOffset, (int)f2.YOffset), png.ToBitmap(box.frameNum), f2.BlendOp);
}
else
{
box.frameNum = 0;
box.prevBuffer = null;
ClearFrame(box.buffer);
RenderNextFrame(box.buffer, Point.Empty, png.ToBitmap(box.frameNum), APNGLib.Frame.BlendOperation.SOURCE);
}
pb.Invalidate();
}
}
}
private void DisposeBuffer(Bitmap buffer, Rectangle region, APNGLib.Frame.DisposeOperation dispose, Bitmap prevBuffer)
{
using (Graphics g = Graphics.FromImage(buffer))
{
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
Brush b = new SolidBrush(Color.Transparent);
switch (dispose)
{
case APNGLib.Frame.DisposeOperation.NONE:
break;
case APNGLib.Frame.DisposeOperation.BACKGROUND:
g.FillRectangle(b, region);
break;
case APNGLib.Frame.DisposeOperation.PREVIOUS:
if(prevBuffer != null)
{
g.FillRectangle(b, region);
g.DrawImage(prevBuffer, region, region, GraphicsUnit.Pixel);
}
break;
default:
break;
}
}
}
private void RenderNextFrame(Bitmap buffer, Point point, Bitmap nextFrame, APNGLib.Frame.BlendOperation blend)
{
using(Graphics g = Graphics.FromImage(buffer))
{
switch(blend)
{
case APNGLib.Frame.BlendOperation.OVER:
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
break;
case APNGLib.Frame.BlendOperation.SOURCE:
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
break;
default:
break;
}
g.DrawImage(nextFrame, point);
}
}
private void ClearFrame(Bitmap buffer)
{
using(Graphics g = Graphics.FromImage(buffer))
{
g.Clear(Color.Transparent);
}
}

Categories