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();
}
}
Related
I've got problem with moving selected file in listview using button to another folder, my code:
public void button2_Click(object sender, EventArgs e)
{
string[] files = Directory.GetFiles(#"C:\Users\Mkzz\Desktop\doki");
string destinyFodler = #"C:\Users\Mkzz\Desktop\doki\test1\*.tif";
listView1.Dispose();
foreach (string file in files)
{
File.Move(file, destinyFodler);
}
}
It gives me error „The process cannot access the file because it is being used by another process.”. Files loaded to listview are .tif ' s images, they are also loaded into picturebox.
Is there any way to fix this?
Try loading the PictureBox controls using a clone image e.g.
public class ImageHelpers
{
public static Image LoadImageClone(string Path)
{
Bitmap imageClone = null;
var imageOriginal = Image.FromFile(Path);
imageClone = new Bitmap(imageOriginal.Width, imageOriginal.Height); // create clone, initially empty, same size
using (var gr = Graphics.FromImage(imageClone))
{
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
gr.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighSpeed;
gr.DrawImage(imageOriginal, 0, 0, imageOriginal.Width, imageOriginal.Height); //copy original image onto this surface
}
imageOriginal.Dispose();
return imageClone;
}
}
Test we can delete the image after assigning the image to a PictureBox
private void LoadImageButton_Click(object sender, EventArgs e)
{
pictureBox1.Image = ImageHelpers.LoadImageClone("Folders.png");
File.Delete("Folders.png");
}
Note I'm not the author of this code, picked the code up many years ago.
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;
}
int countimages = 0;
private void timer1_Tick(object sender, EventArgs e)
{
Image img = sc.CaptureWindowToMemory(windowHandle);
Bitmap bmp = new Bitmap(img,img.Width,img.Height);
bmp.Save(#"e:\screenshotsofpicturebox1\screenshot" + countimages + ".bmp");
bmp.Dispose();
string[] images = Directory.GetFiles(#"e:\screenshotsofpicturebox1\", "*.bmp");
if (images.Length > 0)
{
if (pictureBox1.Image != null)
{
File.Delete(images[0]);
countimages = 0;
pictureBox1.Image.Dispose();
}
pictureBox1.Image = Image.FromFile(images[countimages]);
}
countimages += 1;
label1.Text = countimages.ToString();
}
I want to save image to the hard disk
load the image to the pictureBox1
after the image loaded to pictureBox1 delete the file from the hard disk
save a new image to the hard disk and load it to the pictureBox1
delete the file and so on each time with a new image.
The problem for now is i'm getting exception on the line:
File.Delete(images[0]);
The process cannot access the file e:\screenshotsofpicturebox1\screenshot0.bmp because it is being used by another process.
Another problem I saw now it's saving each time a new file to the hard disk
screenshot0.bmp
screenshot1.bmp
But I wan to be only one file each time screenshot0.bmp and just to replace it each time with a new image.
Reading your code I assume you are trying to show the screen in the picturebox on each tick event.
So, if that is your objective, you don't need to save/delete it, just assign the Image object to the PictureBox Image property like this:
private void timer1_Tick(object sender, EventArgs e) {
Image refToDispose = pictureBox1.Image;
pictureBox1.Image = sc.CaptureWindowToMemory(windowHandle);
refToDispose.Dispose();
}
If you want to save/delete it anyway, you can't pass a directly loaded bitmap from the file to the PictureBox because it will lock the file while in use.
Instead you can create a graphics object from another Bitmap instance with the size of the image and draw it, so the new Bitmap will be a copy without the file lock that you can assign to the PictureBox.
In your code change this:
pictureBox1.Image = Image.FromFile(images[countimages]);
To this:
using (Image imgFromFile = Image.FromFile(images[countimages])) {
Bitmap bmp = new Bitmap(imgFromFile.Width, imgFromFile.Height);
using (Graphics g = Graphics.FromImage(bmp)) {
g.DrawImage(imgFromFile, new Point(0, 0));
}
pictureBox1.Image = bmp;
}
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.
I'm trying to take a picture element from a website and display it inside a PictureBox.. The code doesn't return any errors, but nothing is displayed.
I'm using a WebBrowser class and trying to display the elements using an event that invokes once the webpage is done loading
void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
pictureBox1.ImageLocation = wb.Document.GetElementById("ctl00_mainContent_identityBar_emblemImg").InnerText; // does nothing
label1.Text = "Last Played: " + wb.Document.GetElementById("ctl00_mainContent_lastPlayedLabel").InnerText; // works fine
}
Here's an example of the webpage I'm trying to pull the image from: http://halo.bungie.net/Stats/Halo3/Default.aspx?player=SmitherdxA27
^It's the bird with the orange background on that example.
Pretty easy:
private void Form1_Load(System.Object sender, System.EventArgs e)
{
webBrowser1.Navigate("http://halo.bungie.net/Stats/Halo3/Default.aspx?player=SmitherdxA27");
}
private void WebBrowser1_DocumentCompleted(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
{
if ((e.Url.ToString() == "http://halo.bungie.net/Stats/Halo3/Default.aspx?player=SmitherdxA27"))
{
HtmlElement elem = webBrowser1.Document.GetElementById("ctl00_mainContent_identityStrip_EmblemCtrl_imgEmblem");
string src = elem.GetAttribute("src");
this.pictureBox1.ImageLocation = src;
}
}
Good luck!
It returns nothing because an image tag doesnt contain inner text. You need to use the the element and generate a bitmap.
public Bitmap GetImage(string id)
{
HtmlElement e = webBrowser1.Document.GetElementById(id);
IHTMLImgElement img = (IHTMLImgElement)e.DomElement;
IHTMLElementRenderFixed render = (IHTMLElementRenderFixed)img;
Bitmap bmp = new Bitmap(e.OffsetRectangle.Width, e.OffsetRectangle.Height);
Graphics g = Graphics.FromImage(bmp);
IntPtr hdc = g.GetHdc();
render.DrawToDC(hdc);
g.ReleaseHdc(hdc);
return bmp;
}