Picture Box doesn't updates when setting Image object - c#

I have a problem displaying image object on the pictureBox. I have the following method:
private async void scanButton_Click(object sender, EventArgs e)
{
var guid = await client.ScanRegionAsync(new Point(0, 0), new Size(200, 200));
var currentImage = new ImageData();
while (currentImage.TransmissionStatus != TransmissionStatus.ProcessStop)
{
currentImage = client.GetImage(guid);
if (currentImage.TransmissionStatus.Equals(TransmissionStatus.Image))
{
stitching.AttachImageToScene(currentImage.ImageBytes, currentImage.StartPoint);
}
}
pictureBox1.Image = stitching.CurrentImage;
stitching.CurrentImage.Save(#"c:\stitch.jpg", ImageFormat.Jpeg);
}
and the thing is that picture DOES get saved ok, but pictureBox DOESN'T show it for some reason.
P.S. I tried Refresh/Update, tried to clone image, tried to make method synchronous - same result.

Related

How can I place a border color in a pictureBox if the image loaded in it is from the resources?

I set my pictureBox with a default image from resources with this:
public Form1()
{
InitializeComponent();
pictureBox1.Image = Properties.Resources.default_Employee_Image;
}
when I check if the picture in the pictureBox is from resources with this code, it doesn't draw the border:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
//pictureBox border color
Color themeColor = Color.FromArgb(172, 188, 212);
if (pictureBox1.Image == null) //if image from db is null display default image
{
pictureBox1.Image = Properties.Resources.default_Employee_Image;
}
//if image is the default image: paint border
if (pictureBox1.Image == Properties.Resources.default_Employee_Image)
{
ControlPaint.DrawBorder(e.Graphics, pictureBox1.ClientRectangle, themeColor, ButtonBorderStyle.Solid);
}
}
Also if image from the pictureBox is default, I'll save it as null in my database.
I want to only have a border if the default image is loaded. If I select another image the border should be gone.
If the pictureBox has the default image it should look like this (which means that I still have not selected a picture of the user):
But if the picture in my pictureBox is not the default image-(the image in my resources), [This means that I already selected an image] it should look like this:
And not like this:
pictureBox1.Image == Properties.Resources.SomeImage will never return true, because every time that you call Properties.Resources.SomeImage, it returns a new instance of the image.
You don't need to track the assigned image; instead, you need to track the status. You can use either of the following options:
Rely on a flag: You can set a flag like bool isDefaultImage = true; at form level and if at some point of your application you changed the image, set it to true. Something like this:
if(isDefaultImage)
{
//draw border
}
Rely on Model/DataSource: You can also rely on your model/data source values and instead of checking UI elements, check if the user has a profile picture. Something like this:
if(myUserObject.ProfilePicture == null)
{
//draw border
}
Compare two images
Anyhow, just in case you are interested to compare two Image objects to see whether they are same Image, you can use the following method:
public bool AreImagesEqual(Image img1, Image img2)
{
ImageConverter converter = new ImageConverter();
byte[] bytes1 = (byte[])converter.ConvertTo(img1, typeof(byte[]));
byte[] bytes2 = (byte[])converter.ConvertTo(img2, typeof(byte[]));
return Enumerable.SequenceEqual(bytes1, bytes2);
}
Then you can use it like this:
using(var image = Properties.Resources.DefaultImage)
{
var isDefaultImage = AreImagesEqual(pictureBox1.Image, image);
if(isDefaultImage)
{
//draw border
}
}
I have found a solution for my problem, I have changed my approach (Rely on a flag approach [by #Reza Aghaei]), and instead of comparing pictureBox image with the resource image, I just checked if pictureBox1.Tag is null or not:
On my constructor:
public Form1()
{
InitializeComponent();
pictureBox1.Image = Properties.Resources.default_Employee_Image; //the default image from resources
pictureBox1.Image = null;
}
On my dataGridView cell click event:
private void dataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
{
try
{
if (e.RowIndex != -1)
{
//Display user image
using (SqlConnection con = new SqlConnection(connectionStringConfig))
using (SqlCommand sqlCmd = new SqlCommand("SELECT user_image FROM dbo.Employee_Image WHERE employee_id=#employee_id", con))
{
con.Open();
sqlCmd.Parameters.Add("#employee_id", SqlDbType.NVarChar).Value = EmployeeId;
using (SqlDataReader reader = sqlCmd.ExecuteReader())
{
if (reader.HasRows)
{
reader.Read();
pictureBox1.Image = ImageOperations.BytesToImage((byte[])(reader.GetValue(0)));
if (reader.GetValue(0) == null) //if image is null add border color to tag
{
pictureBox1.Tag = my_color_here;
}
else
{
pictureBox1.Tag = null;
}
}
else
{
pictureBox1.Image = null;
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show($"Something is wrong with the selected record! \nError: { ex.GetType().FullName }");
}
}
On BytesToImage method in ImageOperations class:
public static Image BytesToImage(byte[] buffer) //Get image from database
{
using (MemoryStream ms = new MemoryStream(buffer))
{
return Image.FromStream(ms);
}
}
And on my pictureBox paint event:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
//if image is not present in the picturebox -> paint its border
if (pictureBox1.Image == null)
{
pictureBox1.Tag = my_color_here;
pictureBox1.Image = Properties.Resources.default_Employee_Image;
}
if (pictureBox1.Tag != null) //if tag has a value -> paint the border (this happens if image form db is null)
{
ControlPaint.DrawBorder(e.Graphics, pictureBox1.ClientRectangle, my_color_here, ButtonBorderStyle.Solid);
}
}

How to detect when the image appears in PictureBox

I have a problem about System.Windows.Forms.PictureBox. I want to show a image on monitor and capture it on the camera. So I use Winform which include a picturebox. The picture box is:
PictureBox pb = new PictureBox();
pb.WaitOnLoad = true;
When I set a bitmap to PictureBox and capture the image from camera,
// Show bmp1
this.image.Image = bmp1;
this.image.Invalidate();
this.image.Refresh();
// Delay 1s
UseTimerToDelay1s();
// Show bmp2
this.image.Image = bmp2;
this.image.Invalidate();
this.image.Refresh();
// Capture
CaptureImageFromCamera();
It only capture the bmp1.
If I add a small delay like this,
this.image.Image = bmp2;
this.image.Invalidate();
this.image.Refresh();
UseTimerToDelay100ms();
CaptureImageFromCamera();
It capture bmp2. The Image set method seem to be a async method. Does any method to confirm the image is set? Thanks.
I'd use the first Paint event after assigning the new Image.
You can give it a try using a very large image url from this site.
The example uses google logo image url. Copy the following code and make sure you assign event handlers to the events:
bool newImageInstalled = true;
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.WaitOnLoad = true;
}
private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
if (!newImageInstalled)
{
newImageInstalled = true;
BeginInvoke(new Action(() =>
{
//Capturing the new image
using (var bm = new Bitmap(pictureBox1.ClientSize.Width,
pictureBox1.ClientSize.Height))
{
pictureBox1.DrawToBitmap(bm, pictureBox1.ClientRectangle);
var tempFile = System.IO.Path.GetTempFileName() + ".png";
bm.Save(tempFile, System.Drawing.Imaging.ImageFormat.Png);
System.Diagnostics.Process.Start(tempFile);
}
}));
}
}
private void button1_Click(object sender, EventArgs e)
{
newImageInstalled = false;
pictureBox1.ImageLocation =
"https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png";
}
private void button2_Click(object sender, EventArgs e)
{
newImageInstalled = false;
pictureBox1.Image = null;
}

Save webbrowser control as image

I'm trying to get webbrowser control as image. But when my code gives me a full screen image. I want to get only webbrowser image. How should I fix my code to get the right image?
Bitmap memoryImage;
private void button2_Click(object sender, EventArgs e)
{
Graphics myGraphics = webBrowser1.CreateGraphics();
Size s = webBrowser1.Size;
memoryImage = new Bitmap(webBrowser1.Width,webBrowser1.Height, myGraphics);
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
memoryGraphics.CopyFromScreen(webBrowser1.Location.X, webBrowser1.Location.Y, 0, 0, s);
memoryImage.Save("C:\\Users\\Koo\\Desktop\\NaverMap.png");
Use the following code - Which supported and does work, but not always works fine.
In some circumstances you will get a blank image screenshot(when there is a more complex html it loads, the more possible it fails)
using (var browser = new System.Windows.Forms.WebBrowser())
{
browser.DocumentCompleted += delegate
{
using (var pic = new Bitmap(browser.Width, browser.Height))
{
browser.DrawToBitmap(pic, new Rectangle(0, 0, pic.Width, pic.Height));
pic.Save(imagePath);
}
};
browser.Navigate(Server.MapPath("~") + htmlPath); //a file or a url
browser.ScrollBarsEnabled = false;
while (browser.ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete)
{
System.Windows.Forms.Application.DoEvents();
}
}

I want to delete an image on longpress on the image in canvas

I have use the given below code to display the image on canvas and now I want to delete the displayed image on the long press on that image. I try the contextmenu for that but it not works. please anybody tell me how i can do it or properly used contextmenu for it
private void Stickers1_SelectionChanged(object sender, SelectionChangedEventArgs e) {
var selecteditem = e.AddedItems[0] as StickersImageListModel;
Stickers1.Visibility = Visibility.Collapsed;
// taking image from a list StickersImageListModel of images and bind with imageitem varaible
Image imageitem = new Image();
BitmapImage image = new BitmapImage(new System.Uri(selecteditem.Imageurl, UriKind.Absolute));
imageitem.Source = image;
//Add the images on canvas
my_canvas.Children.Add(imageitem);
imageitem.AllowDrop = true;
// DRag and drop the images on canvas
imageitem.ManipulationMode = ManipulationModes.All;
imageitem.ManipulationDelta += Drag_ManipulationDelta;
CompositeTransform ct = new CompositeTransform();
imageitem.RenderTransform = ct;
my_canvas.Visibility = Visibility.Visible;
}
You can use Holding event for image. However you have to note that Holding event wont be fired for desktop apps instead you have to use RightTapped event.
If you are targetting only to mobile apps you can use Holding event
// imageitem.RightTapped += Imageitem_RightTapped;
imageitem.Holding += Imageitem_Holding;
imageitem.IsRightTapEnabled = true;
imageitem.IsHoldingEnabled = true;
private void Imageitem_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
mycanvas.Children.Remove(sender as Image);
}
private void Imageitem_Holding(object sender, HoldingRoutedEventArgs e)
{
mycanvas.Children.Remove(sender as Image);
}

load image on canvas when navigate.. which is on other canvas in other page with c# and xaml in windows app

I have used the following code to pick image on a canvas.Now I want add this image on another canvas which is on different page when am navigate to it.
private async void edit_click(object sender, RoutedEventArgs e)
{
Windows.Storage.Pickers.FileOpenPicker filepicker = new Windows.Storage.Pickers.FileOpenPicker();
filepicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
filepicker.FileTypeFilter.Add(".jpg");
filepicker.FileTypeFilter.Add(".png");
filepicker.FileTypeFilter.Add(".bmp");
filepicker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
Windows.Storage.StorageFile imageFile = await filepicker.PickSingleFileAsync();
if (imageFile != null)
{
Windows.UI.Xaml.Media.Imaging.BitmapImage bitmap = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
Windows.Storage.Streams.IRandomAccessStream stream = await imageFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
Image newImage = new Image();
bitmap.SetSource(stream);
newImage.Source = bitmap;
newImage.Height = 250;
newImage.Stretch = Stretch.UniformToFill;
newImage.ManipulationMode = ManipulationModes.All;
this.theCanvas.Children.Add(newImage);
}
}
private void save_click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(showdp));
}
You can do in many ways, one is create a static repository of images like:
public class Settings
{
public static Image CanvasImage;
}
And set that in your code, in edit click or where you consider, and you can get and set from any part of the app using:
Settings.CanvasImage = ...

Categories

Resources