Code freezes my application - c#

This code extremly freezes the WPF application.
Is there ANY chance to fix it?
var getScreenshot = Task.Factory.StartNew(() =>
{
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new ThreadStart(() => {
#region Main
try
{
Graphics gfx;
Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
gfx = Graphics.FromImage(bmp);
WindowInteropHelper windowInteropHelper = new WindowInteropHelper(this);
Screen screen = Screen.FromHandle(windowInteropHelper.Handle);
gfx.CopyFromScreen(screen.Bounds.X, screen.Bounds.Y, 0, 0, screen.Bounds.Size, CopyPixelOperation.SourceCopy);
MemoryStream ms = new MemoryStream();
byte[] bitmapData = null;
using (bmp)
{
bmp.SetResolution(72, 72);
ImageCodecInfo myImageCodecInfo;
myImageCodecInfo = GetEncoderInfo("image/jpeg");
System.Drawing.Imaging.Encoder myEncoder;
myEncoder = System.Drawing.Imaging.Encoder.Quality;
EncoderParameters encoderParameters = new EncoderParameters();
EncoderParameter encoderParameter = new EncoderParameter(myEncoder, 25L);
encoderParameters.Param[0] = encoderParameter;
bmp.Save(ms, myImageCodecInfo, encoderParameters);
bitmapData = ms.ToArray();
}
if (bitmapData != null)
DataProvider.UpdateScreen(((PlayerConfiguration)App.Current.Properties["PlayerConfig"]).InstallationKey, bitmapData);
}
catch (Exception ex)
{
#region Error
LogEntry l = new LogEntry();
l.Message = string.Format("{0}", ex.Message);
l.Title = "GetScreen() Error";
l.Categories.Add(Category.General);
l.Priority = Priority.Highest;
CustomLogger.WriteErrorLog(l, "GetScreen");
#endregion
}
#endregion
}));
}, TaskCreationOptions.LongRunning)
.ContinueWith(x => x.Dispose());

Yes, just don't dispatch to the UI thread for the whole thing. Only put the smallest amount of code into the Invoke call that you can get away with. It should be when you're actually updating the UI. Since the whole thing is in the invoke call in your code, the UI is blocked until the whole thing finishes.

Related

Convert WriteableBitmap to VideoFrame - A generic error occurred in GDI+

So i try to use ONNX file for local object detection, work great in UWP and WPF with local saved image.
Now, the problem is, to use my detection algorithm with 3D live camera.
My detection algorithm expect a (Windows.Media.)VideoFrame, and my camera give me an (System.Windows.Media.Imaging.)WriteableBitmap.
So here what i have donne already :
Convert my WriteableBitmap to Bitmap :
private System.Drawing.Bitmap BitmapFromWriteableBitmap(System.Windows.Media.Imaging.WriteableBitmap writeBmp)
{
System.Drawing.Bitmap bmp;
using (MemoryStream outStream = new MemoryStream())
{
System.Windows.Media.Imaging.BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create((System.Windows.Media.Imaging.BitmapSource)writeBmp));
enc.Save(outStream);
bmp = new System.Drawing.Bitmap(outStream);
}
return bmp;
}
Now i want to tranform my Bitmap to SoftwareBitmap (for creating a VideoFrame with VideoFrame.CreateWithSoftwareBitmap)
Windows.Storage.Streams.InMemoryRandomAccessStream stream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
Stream strm;
private async Task<SoftwareBitmap> SoftWareBitmapFromBitmap(Bitmap bitmap)
{
SoftwareBitmap softwareBitmap2;
strm = stream.AsStream();
bitmap.Save(strm, ImageFormat.Png);
Windows.Graphics.Imaging.BitmapDecoder decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
softwareBitmap2 = await decoder.GetSoftwareBitmapAsync();
return softwareBitmap2;
}
But in this last function i got an error in :
bitmap.Save(strm, ImageFormat.Bmp);
I got the "A generic error occurred in GDI+."
I have try to lock/unlock the bitmap, i have try different ImageFormat, if i change to 'ImageFormat.MemoryBmp' i got an "Value cannot be null".
Thank you.
I dont know how to quotes or thumb up answer and sorry for that.
That work great just with : outStream.AsRandomAccessStream()
Here the final function :
public async Task<System.Windows.Shapes.Rectangle> GetPositionDetection(WriteableBitmap wrtBitmap, double imageWidth, double imageHeight)
{
try
{
MemoryStream outStream = new MemoryStream();
System.Windows.Media.Imaging.BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create((System.Windows.Media.Imaging.BitmapSource)wrtBitmap));
enc.Save(outStream);
Windows.Storage.Streams.InMemoryRandomAccessStream stream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
Windows.Graphics.Imaging.BitmapDecoder decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(outStream.AsRandomAccessStream());
SoftwareBitmap tmp2 = await decoder.GetSoftwareBitmapAsync();
VideoFrame inputImage = VideoFrame.CreateWithSoftwareBitmap(tmp2);
IList<PredictionModel> ResultsList = await objDetec.PredictImageAsync(inputImage);
if (ResultsList.Count == 0)
{
Console.WriteLine("Object not detected");
return null;
}
else
{
var itm = ResultsList.First(x => x.Probability == ResultsList.Max(y => y.Probability));
System.Windows.Shapes.Rectangle rct = new System.Windows.Shapes.Rectangle();
rct.Stroke = System.Windows.Media.Brushes.Red;// new SolidColorBrush(Windows.UI.Colors.Red);
rct.StrokeThickness = 2;
rct.Width = imageWidth * (MappingEchellefloat(0, 1, 0, 100, itm.BoundingBox.Width) / 100);
rct.Height = imageHeight * (MappingEchellefloat(0, 1, 0, 100, itm.BoundingBox.Height) / 100);
Console.WriteLine("Object returned : " + ResultsList.Count);
return rct;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
Thank you for your help.

How to cretae a bitmap image from a byte arrayin androidwith java?

I have a c# tcp server and i send a image byte array to my android client. But i have no success to convert array to bitmap.
This is my c# code:
new Thread(() =>{
//İmage converter
ImageConverter imConv = new ImageConverter();
//memory streaö
MemoryStream ms = new MemoryStream();
//bitmap
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format16bppRgb555);
Graphics g = Graphics.FromImage(bitmap);
g.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
Cursors.Default.Draw(g, new Rectangle(new Point(Cursor.Position.X, Cursor.Position.Y), new Size(Cursors.Default.Size.Width, Cursors.Default.Size.Height)));
bitmap.Save(ms, ImageFormat.Png);
Image img = Image.FromStream(ms);
byte[] imgArry = (byte[])imConv.ConvertTo(img,typeof(byte[]));
tcpManager.SendTo(socket,imgArry);
bitmap.Dispose();
ms.Close();
ms.Dispose();
Thread.Sleep(41);
}).Start();
And this is my android client code, i get successfully the byte array but the function returns me a null bitmap
#Override
public void OnReceived(byte[] byteData) {
try{
final Bitmap bitmap = BitmapFactory.decodeByteArray(byteData, 0, byteData.length);
runOnUiThread(new Runnable() {
#Override
public void run() {
screenView.setImageBitmap(bitmap);
}
});
}catch (Exception ex){
}
}

Implement Barcode in MVC

I want to Implement Barcode in MVC web App hosted on IIS, for Super Store. After 3 day research i found an example on google but that was not in MVC. Please tell me how can i Implement this code in MVC, so when i pass a string barcode image display in my view
public void CreateBarcode(string code)
{
var myBitmap = new Bitmap(500, 50);
var g = Graphics.FromImage(myBitmap);
var jgpEncoder = GetEncoder(ImageFormat.Jpeg);
g.Clear(Color.White);
var strFormat = new StringFormat { Alignment = StringAlignment.Center };
g.DrawString(code, new Font("Free 3 of 9", 50), Brushes.Black, new RectangleF(0, 0, 500, 50), strFormat);
var myEncoder = System.Drawing.Imaging.Encoder.Quality;
var myEncoderParameters = new EncoderParameters(1);
var myEncoderParameter = new EncoderParameter(myEncoder, 100L);
myEncoderParameters.Param[0] = myEncoderParameter;
myBitmap.Save(#"E:\Barcode.jpg", jgpEncoder, myEncoderParameters);
}
public ImageCodecInfo GetEncoder(ImageFormat format)
{
var codecs = ImageCodecInfo.GetImageDecoders();
foreach (var codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
It looks like you know how to make a barcode and need to know how to get it from a controller to your page. Here is a little code that may help you put it all together.
in your page
<img src="#Url.Action("Barcode", new { code = "*ABC123*" })" alt="" />
in your controller
public ActionResult Barcode(string code)
{
var myBitmap = new Bitmap(500, 50);
var g = Graphics.FromImage(myBitmap);
// the code that makes the barcode
// the code that makes the barcode
// the code that makes the barcode
// Put the image into a stream to return
MemoryStream ms = new MemoryStream();
myBitmap.Save(ms, ImageFormat.Png);
// Reset the stream position before returning it
ms.Position = 0;
return new FileStreamResult(ms, "image/png");
}

A generic error occurred in GDI+ when scaling an image

I'm trying to scale an image and save that image to a new location. Now i'm having this error "A generic error occurred in GDI+ at System.Drawing.Image.Save".
I've found a couple of answers on stackoverflow, unfortunately without any results.
public static void SaveImageScaled(String imagePath, string destPath, Size newSize, String filename)
{
using (Bitmap bmpOriginal = (Bitmap)Image.FromFile(imagePath))
using (Bitmap bmpResized = new Bitmap(newSize.Width, newSize.Height))
using (Graphics g = Graphics.FromImage(bmpResized))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(
bmpOriginal,
new Rectangle(Point.Empty, bmpResized.Size),
new Rectangle(Point.Empty, bmpOriginal.Size),
GraphicsUnit.Pixel);
// Lower the quality;
long qualityPercentage = 75L;
ImageCodecInfo[] myImageCodecInfoList = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo myImageCodecInfo = myImageCodecInfoList.Where(x => x.FormatID == bmpOriginal.RawFormat.Guid).First();
Encoder myEncoder = Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, qualityPercentage);
myEncoderParameters.Param[0] = myEncoderParameter;
if (!Directory.Exists(destPath))
Directory.CreateDirectory(destPath);
// ERROR
bmpResized.Save(destPath + filename, myImageCodecInfo, myEncoderParameters);
}
}
This code created a directory with insufficient write-acces. Changed the permissions on a higher directory level, and solved the issue.
if (!Directory.Exists(destPath))
Directory.CreateDirectory(destPath);

Displaying, downloading, and saving a jpeg image from server to Windows Phone 8 camera roll

I am trying to retrieve an image from a specific URL, display it in my image box, and then finally save it to my camera roll. This is what I have tried but I am getting a target invocation exception. What does that suggest?
private void downloadImg()
{
String uri = "http://timenewsfeed.files.wordpress.com/2013/12/doge.jpg";
Uri imgUri = new Uri(uri, UriKind.Absolute);
ImageSource imgSource = new BitmapImage(imgUri);
Dispatcher.BeginInvoke(() =>
{
imageBox.Source = imgSource;
}
);
using (var mediaLibrary = new MediaLibrary())
{
using (var stream = new MemoryStream())
{
Debug.WriteLine("trying to save photo...");
var fileName = "HELLOWORLD.jpg";
BitmapImage img = new BitmapImage(imgUri);
img.CreateOptions = BitmapCreateOptions.None;
img.ImageOpened += (s, e) =>
{
WriteableBitmap bmp = new WriteableBitmap((BitmapImage)s);
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
};
stream.Seek(0, SeekOrigin.Begin);
Dispatcher.BeginInvoke(() =>
{
var picture = mediaLibrary.SavePicture(fileName, stream);
});
// or to cameraroll
Debug.WriteLine("photo saved");
}
}
}
I see at least one potential issue with your code. The main issue I see is in the order things execute in your method which could cause the stream to be empty when you try to save it. You do a handling for ImageOpened which fills the stream, but that callback is executed asynchronously. In other words, this
stream.Seek(0, SeekOrigin.Begin);
Dispatcher.BeginInvoke(() =>
{
var picture = mediaLibrary.SavePicture(fileName, stream);
});
may execute before this
WriteableBitmap bmp = new WriteableBitmap((BitmapImage)s);
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
If you moved the logic for saving up to ImageOpened handler, it may fix the issue. So you'd have something like this...
img.ImageOpened += (s, e) =>
{
WriteableBitmap bmp = new WriteableBitmap((BitmapImage)s);
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
Dispatcher.BeginInvoke(() =>
{
var picture = mediaLibrary.SavePicture(fileName, stream);
});
};

Categories