I want to take screenshot of a Div Element in asp.net and save it to disk. I don't want to use html2canvas library or html5 canvas element. Approach can be Server side or Client Side.
Untested, but found this:
public Bitmap GenerateScreenshot(string url, int width, int height)
{
// Load the webpage into a WebBrowser control
WebBrowser wb = new WebBrowser();
wb.ScrollBarsEnabled = false;
wb.ScriptErrorsSuppressed = true;
wb.Navigate(url);
while (wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
// Set the size of the WebBrowser control
wb.Width = width;
wb.Height = height;
if (width == -1)
{
// Take Screenshot of the web pages full width
wb.Width = wb.Document.Body.ScrollRectangle.Width;
}
if (height == -1)
{
// Take Screenshot of the web pages full height
wb.Height = wb.Document.Body.ScrollRectangle.Height;
}
// Get a Bitmap representation of the webpage as it's rendered in the WebBrowser control
Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
wb.Dispose();
return bitmap;
}
http://pietschsoft.com/post/2008/07/c-generate-webpage-thumbmail-screenshot-image.aspx
Related
How to add watermark image while uploading image in asp.net mvc.
I am using jquery.uploadfile.min.js multiple file upload for uploading image.
Want to add automatically stored logo image (watermark) to append in my image file that i am going to upload.
IN VIEW:
var errorOccured = false;
$(function () {
var uploadObj = $("#multipleupload").uploadFile({
url: "./Handler.ashx",
multiple: true,
fileName: "myfile",
maxFileSize: 1024 * 5000,
allowedTypes: "jpg,jpeg,gif,png",
autoSubmit: false,
formData: { "FunctionName": "UploadProductImage", "ProductID": '#clsEncrypt.Encrypt(ViewBag.ProductID.ToString())' }, //"ImgResizeOption": ImgResizeOption
afterUploadAll: function () {
if (!errorOccured) {
window.location.href = 'ProductImage?Product=#(clsEncrypt.Encrypt(ViewBag.ProductID.ToString()))';
}
},
onError: function (files, status, errMsg) {
alert('file(s) could not be uploaded. Error: ' + errMsg);
errorOccured = true;
}
});
$("#startUpload").click(function () {
uploadObj.startUpload();
});
});
IN HANDLER :
public void UploadProductImage()
{
int ProductID = Convert.ToInt32(clsEncrypt.Decrypt(HttpContext.Current.Request["ProductID"]));
string PhysicalFolderPath = "~/Images/Product/";
for (int j = 0; j < HttpContext.Current.Request.Files.Count; j++)
{
HttpPostedFile uploadFile = HttpContext.Current.Request.Files[j];
string extention = System.IO.Path.GetExtension(uploadFile.FileName);
UploadPic(uploadFile, j++, PhysicalFolderPath, ProductID);
}
}
protected void UploadPic(HttpPostedFile FUPhoto, int sort, string RemotePath, int ProductID)
{
if (FUPhoto.FileName != "")
{
string ImgUploadResponse = "";
string strExt = Path.GetExtension(FUPhoto.FileName).Trim().ToLower();
string ImageName = DateTime.Now.ToFileTimeUtc() + strExt;
string OriginalImageFullPath = "~/Images/Product/" + ImageName;
if (Directory.Exists(HttpContext.Current.Server.MapPath("~/Images/Product/")).Equals(false))
Directory.CreateDirectory(HttpContext.Current.Server.MapPath("~/Images/Product/"));
FUPhoto.SaveAs(HttpContext.Current.Server.MapPath(OriginalImageFullPath));
ProductImageEntity objProdImage = new ProductImageEntity();
objProdImage.ProductID = ProductID;
if (ImgUploadResponse != "")
objProdImage.Image = "";
else
objProdImage.Image = ImageName;
if (!String.IsNullOrEmpty(objProdImage.Image))
new ProductImageBLL().InsertUpdateProductImage(objProdImage);
}
}
Please refer the below code for watermark logo to add from code side.
using (Image image = Image.FromFile(#"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"))
using (Image watermarkImage = Image.FromFile(#"C:\Users\Public\Pictures\Sample Pictures\watermark.png"))
using (Graphics imageGraphics = Graphics.FromImage(image))
using (TextureBrush watermarkBrush = new TextureBrush(watermarkImage))
{
int x = (image.Width / 2 - watermarkImage.Width / 2);
int y = (image.Height / 2 - watermarkImage.Height / 2);
watermarkBrush.TranslateTransform(x, y);
imageGraphics.FillRectangle(watermarkBrush, new Rectangle(new Point(x, y), new Size(watermarkImage.Width+1, watermarkImage.Height)));
image.Save(#"C:\Users\Public\Pictures\Sample Pictures\Desert_watermark.jpg");
}
I have installed and tried your dll. Everything is good but one issue. The watermark text is added vertically to vertical images (images whose height is bigger than width). Better solution is to add watermark in a horizantal line to vertical images as well as horizantal images. Thanks anyway.
--Edit--
I have solved the problem within this code, which checks and changes the orientation of the image in need. (uploadedImage is the image that i read from stream)
if (uploadedImage.PropertyIdList.Contains(0x0112))
{
PropertyItem propOrientation = uploadedImage.GetPropertyItem(0x0112);
short orientation = BitConverter.ToInt16(propOrientation.Value, 0);
if (orientation == 6)
{
uploadedImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
}
else if (orientation == 8)
{
uploadedImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
}
else
{
// Do nothing
}
}
Recently I've published a nugget package that do add image water mark with control over opacity and target spot to place the watermark in. Additionally you can add text watermark and do image crop/resize as well.
install via nugget:
Install-Package LazZiya.ImageResize
then you can use the code as below:
//get image from local path
var img = Image.FromFile("wwwroot\\images\\lum3n-358833-unsplash.jpg");
//scale and crop, 600x250 center focus
var newImg = ImageResize.ScaleAndCrop(img, 600, 250, TargetSpot.Center);
//watermark image path
var imgWatermark = "wwwroot\\images\\icon.png";
//add image watermark
newImg.ImageWatermark(imgWatermark,
TargetSpot.TopRight, //define target spot
10, //margin
37); //opacity (0-100)
//save new image
newImg.SaveAs("wwwroot\\images\\600x250-image-watermark.jpg");
//dispose to free up memory
img.Dispose();
newImg.Dispose();
[UPDATE]
The package is updated and some methods has been changed, and better support for more image formats is available (including animated gif).
See the docs for more details.
see live demo page.
I want to show a lot of images in a form using User Control, but it's very slow and takes a lot of system memory.
How can I load image in Picture Box when User Control shows to user?
I wrote this sample code. It works fine for 700 images, but I am still looking for best solution.
Bitmap myBitmap;
Image myThumbnail;
foreach (var item in queryMatchingFiles)
{
Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);
myBitmap = new Bitmap(item);
myThumbnail = myBitmap.GetThumbnailImage(120, 183, myCallback, IntPtr.Zero);
flowLayoutPanel1.Controls.Add(new PictureBox {
Image = myThumbnail,
Width = 120,
Height = 183,
BackgroundImageLayout = ImageLayout.Stretch
});
count++;
myBitmap = null;
myThumbnail = null;
}
public bool ThumbnailCallback()
{
return false;
}
I have a simple wpf desktop application which prints a bitmap in landscape mode.
Under Windows 8/8.1 the printout is clipped on the bottom of the page while under Windows 7 it is printed correctly.
The code is really simple: load a bitmap, put it into an Image object, measure the printable area, arrange the image and print.
void printButton_Click(object sender, RoutedEventArgs e)
{
var pd = new PrintDialog();
if (!pd.ShowDialog().Value)
{
return;
}
pd.PrintTicket.PageOrientation = PageOrientation.Landscape;
pd.PrintTicket.PageBorderless = PageBorderless.None;
var printingCapabilities = pd.PrintQueue.GetPrintCapabilities(pd.PrintTicket);
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.UriSource = new Uri("D:\\printTest.bmp");
bitmapImage.EndInit();
var imageuiElement = new Image { Source = bitmapImage };
var desiredSize = new Size(printingCapabilities.PageImageableArea.ExtentWidth, printingCapabilities.PageImageableArea.ExtentHeight);
imageuiElement.Measure(desiredSize);
imageuiElement.Arrange(new Rect(new Point(printingCapabilities.PageImageableArea.OriginWidth, printingCapabilities.PageImageableArea.OriginHeight), imageuiElement.DesiredSize));
pd.PrintVisual(imageuiElement, "MyImage");
}
The bitmap size is 1518 x 1092 pixels, 96 DPI, which is 40.2 x 28.9 cm.
I have found the question Cannot print a document with landscape orientation under Windows 8 (WPF, .NET 4.0)
but there is no good response for my issue (additionally I have no problem with printing as landscape itself).
I have tested it with different printers of different vendors, the printouts are clipped in all of them. A software CutePDF writer prints it to PDF correctly.
Any help appreciated.
It seems that Windows 8 does not draw ui elements outside of their container bounds. This is why the printout was clipped at the bottom.
Anyway, I ended up with a code like this, which is able to print a centered bitmap on a landscape page:
printDialog.PrintTicket.PageOrientation = PageOrientation.Landscape;
printDialog.PrintTicket.PageBorderless = PageBorderless.None;
var printingCapabilities = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
if (printingCapabilities.PageImageableArea == null)
{
return;
}
var document = new FixedDocument();
document.DocumentPaginator.PageSize = new Size(printingCapabilities.PageImageableArea.ExtentWidth, printingCapabilities.PageImageableArea.ExtentHeight);
foreach (var imageStream in imageStreams)
{
document.Pages.Add(GeneratePageContent(imageStream, printingCapabilities, printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight));
}
try
{
printDialog.PrintDocument(document.DocumentPaginator, GlobalConstants.SoftwareName);
}
private PageContent GeneratePageContent(Stream imageStream, PrintCapabilities printingCapabilities, double paperWidth, double paperHeight)
{
imageStream.Seek(0, SeekOrigin.Begin);
var bmp = new BitmapImage();
bmp.BeginInit();
bmp.StreamSource = imageStream;
bmp.EndInit();
var margin = new Thickness();
var pageSize = new Size();
if (printingCapabilities.PageImageableArea != null)
{
margin = new Thickness(
printingCapabilities.PageImageableArea.OriginWidth,
printingCapabilities.PageImageableArea.OriginHeight,
printingCapabilities.PageImageableArea.OriginWidth,
printingCapabilities.PageImageableArea.OriginHeight);
pageSize = new Size(printingCapabilities.PageImageableArea.ExtentWidth, printingCapabilities.PageImageableArea.ExtentHeight);
}
var imageUiElement = new Image
{
Source = bmp,
Margin = margin
};
var canvas = new Grid { Width = paperWidth, Height = paperHeight };
canvas.Children.Add(imageUiElement);
var fixedPage = new FixedPage
{
Width = paperWidth,
Height = paperHeight
};
fixedPage.Children.Add(canvas);
var pageContent = new PageContent();
((IAddChild)pageContent).AddChild(fixedPage);
pageContent.Measure(pageSize);
pageContent.Arrange(new Rect(new Point(), pageSize));
pageContent.UpdateLayout();
return pageContent;
}
This is the code i'm using now:
int imagescount = 0;
private void SaveImageFromWebBrowser()
{
Bitmap bitmap = new Bitmap(webBrowser1.Width, webBrowser1.Height);
webBrowser1.DrawToBitmap(bitmap, new Rectangle(0, 0, webBrowser1.Width, webBrowser1.Height));
bitmap.Save(#"e:\webbrowserimages\wbImage" + imagescount.ToString("D6") + ".bmp",
System.Drawing.Imaging.ImageFormat.Bmp);
bitmap.Dispose();
imagescount++;
}
The problem is some images are larger and then there are scrollbars other images smaller so the webbroswer not need the scrollbars.
But the large images with the scrollbars the image on the hard disk i see the whole webbroswer control with the scrollbars !
I want to get the whole image in the WebBbrowser control. Only the image to save not the whole control !
First you need to add a reference to your project called: Microsoft.mshtml
Then:
int imagescount = 0;
private void SaveImageFromWebBrowser()
{
IHTMLDocument2 doc = (IHTMLDocument2)webBrowser1.Document.DomDocument;
IHTMLControlRange imgRange = (IHTMLControlRange)((HTMLBody)doc.body).createControlRange();
foreach (IHTMLImgElement img in doc.images)
{
imgRange.add((IHTMLControlElement)img);
imgRange.execCommand("Copy", false, null);
using (Bitmap bmp = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap))
{
bmp.Save(#"e:\webbrowserimages\Image" + imagescount.ToString("D6") + ".bmp",
System.Drawing.Imaging.ImageFormat.Bmp);
}
imagescount++;
}
}
Working perfect.
I want to takeScreenShoot() for the first 30 seconds of the video. But when I call it in webBrowser1_DocumentCompleted it stops the video from loading. So the screenshoots will be blank. This is just a rough copy of my code. Is there a way to call takeScreenShoot() after everything is completely loaded and video is playing? or calling it after newForm.ShowDialog(); ?
main(
Form1 newForm = new Form1();
newForm.loadStream();
newForm.ShowDialog();
}
public void loadVideo()
{
//// When the form loads, open this web page.
//this.webBrowser1.Navigate("http://www.dotnetperls.com/");
SuppressScriptErrorsOnly(webBrowser1);
//set browser eumulator to IE8
var appName = Process.GetCurrentProcess().ProcessName + ".exe";
SetIE8KeyforWebBrowserControl(appName);
webBrowser1.Navigate("http://youtu.be/e-ORhEE9VVg?list=PLFgquLnL59alLAsVmUulfe3X-BrPzoYAH");
webBrowser1.ScriptErrorsSuppressed = true;
//Console.WriteLine("loading new new");
}
public void takeScreenShoot()
{
DateTime startTime = DateTime.Now;
int i = 0;
string location = #"F:\Twitch Screenshoot\testing\";
while (true)
{
//If time is greater than 30 seconds start taking picture
if (DateTime.Now.Subtract(startTime).TotalSeconds > 1)
{
if (DateTime.Now.Subtract(startTime).TotalSeconds > i + 1)
{
Console.WriteLine("Taking Picture\n");
// The size of the browser window when we want to take the screenshot (and the size of the resulting bitmap)
Bitmap bitmap = new Bitmap(1024, 768);
Rectangle bitmapRect = new Rectangle(0, 0, 1024, 768);
// This is a method of the WebBrowser control, and the most important part
this.webBrowser1.DrawToBitmap(bitmap, bitmapRect);
// Generate a thumbnail of the screenshot (optional)
System.Drawing.Image origImage = bitmap;
System.Drawing.Image origThumbnail = new Bitmap(120, 90, origImage.PixelFormat);
Graphics oGraphic = Graphics.FromImage(origThumbnail);
oGraphic.CompositingQuality = CompositingQuality.HighQuality;
oGraphic.SmoothingMode = SmoothingMode.HighQuality;
oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
Rectangle oRectangle = new Rectangle(0, 0, 120, 90);
oGraphic.DrawImage(origImage, oRectangle);
// Save the file in PNG format
origThumbnail.Save(location + "Screenshot" + i + ".png", ImageFormat.Png);
origImage.Dispose();
i++;
}
}
//stop taking picture when time is greater than 3.
if (DateTime.Now.Subtract(startTime).TotalMinutes > 1)
{
//should close form here
this.Close();
break;
}
}
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (e.Url.AbsolutePath != (sender as WebBrowser).Url.AbsolutePath)
{
var webBrowser = sender as WebBrowser;
webBrowser.DocumentCompleted -= webBrowser1_DocumentCompleted;
Console.WriteLine("loading {0} \n");
this.takeScreenShoot();
}
}
(Making comment as answer to allow question to close)
I'm pretty sure the issue that the video you linked is Adobe Flash. However taking the screenshot with selenium might work.