I grabbed some code from the link below to generate a screenshot from a web browser control:
http://pietschsoft.com/post/2008/07/C-Generate-WebPage-Thumbmail-Screenshot-Image.aspx
Then, I modified to be an extension method like so:
public static Bitmap GetScreenshot(this WebBrowser webBrowser)
{
// Load the webpage into a WebBrowser control
using (WebBrowser wb = new WebBrowser())
{
wb.ScrollBarsEnabled = false;
wb.ScriptErrorsSuppressed = true;
wb.Navigate(webBrowser.Url);
while (wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
// Set the size of the WebBrowser control
wb.Width = wb.Document.Body.ScrollRectangle.Width;
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));
return bitmap;
}
}
It works great for most web pages, but I am trying to use it for a SharePoint site and the image is coming out as 250x250 every time. :-s
Any geniuses here that can give me a solution?
Thanks in advance
Well, the reason for this seems to be that my new WebBrowser (wb) is uninitialized even after I call Navigate(). The Url property shows as null. This is weird. Does it mean I cannot create a WebBrowser in code and never display it? It would be a shame to have to display the thing. :-(
You can check that question taking-screenshot-of-a-webpage-programmatically.
It is based on this webpage_thumbnailer which uses Web Browser control.
For one, the DrawToBitmap class does not exist under the webbrowser control. I suggest using CopyFromScreen. Here is a code snippet:
Bitmap b = new Bitmap(wb.ClientSize.Width, webBrowser1.ClientSize.Height);
Graphics g = Graphics.FromImage(b);
g.CopyFromScreen(this.PointToScreen(wb.Location), new Point(0, 0), wb.ClientSize);
//The bitmap is ready. Do whatever you please with it!
b.Save(#"c:\screenshot.jpg", ImageFormat.Jpeg);
MessageBox.Show("Screen Shot Saved!");
Related
I have an url that gets team logos but it returns svg https://www.mlbstatic.com/team-logos/141.svg.
How can i display this in a Image for xamarin forms?
Searched and only found complex huge amounts of code.
looking for
Download image -- I have this but what do i need to save it in GetResponsestream preferrable i would like to stay in memory and not write to disk or file.
Attach it to an image to display.
Thanks.
Ok, thought i would post my solution here.
I used SkiSharp:
SkiaSharp.Extended.Svg.SKSvg svg = new SkiaSharp.Extended.Svg.SKSvg();
using (WebClient client = new WebClient())
{
// ie for theurl: https://www.mlbstatic.com/team-logos/141.svg
svg.Load(new MemoryStream(client.DownloadData(new Uri(theurl))));
var bitmap = new SKBitmap((int)svg.CanvasSize.Width, (int)svg.CanvasSize.Height);
var canvas = new SKCanvas(bitmap);
canvas.DrawPicture(svg.Picture);
canvas.Flush();
canvas.Save();
string filename = "";
using (var image = SKImage.FromBitmap(bitmap))
using (var data = image.Encode(SKEncodedImageFormat.Png, 80))
{
// save the data to a stream
filename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp.png");
using (var stream = File.OpenWrite(filename ))
{
data.SaveTo(stream);
}
}
}
use FileName from above to assign source to Xamarin image.
this accomplished the task with the least amount of code lines i tried.
I'm currently trying to create an interop layer to render my render target texture into a Skia SkImage. This is being done to facilitate rendering from my graphics API into Avalonia.
I've managed to piece together enough code to get everything running without any errors (at least, none that I can see), but when I draw the SkImage I see nothing but a black image.
Of course, these things are easier to describe with code:
private EglPlatformOpenGlInterface _platform;
private AngleWin32EglDisplay _angleDisplay;
private readonly int[] _glTexHandle = new int[1];
IDrawingContextImpl context // <-- From Avalonia
_platform = (EglPlatformOpenGlInterface)platform;
_angleDisplay = (AngleWin32EglDisplay)_platform.Display;
IntPtr d3dDevicePtr = _angleDisplay.GetDirect3DDevice();
// Device5 is from SharpDX.
_d3dDevice = new Device5(d3dDevicePtr);
// Texture.GetSharedHandle() is the shared handle of my render target.
_eglTarget = _d3dDevice.OpenSharedResource<Texture2D>(_target.Texture.GetSharedHandle());
// WrapDirect3D11Texture calls eglCreatePbufferFromClientBuffer.
_glSurface = _angleDisplay.WrapDirect3D11Texture(_platform, _eglTarget.NativePointer);
using (_platform.PrimaryEglContext.MakeCurrent())
{
_platform.PrimaryEglContext.GlInterface.GenTextures(1, _glTexHandle);
}
var fbInfo = new GRGlTextureInfo(GlConsts.GL_TEXTURE_2D, (uint)_glTexHandle[0], GlConsts.GL_RGBA8);
_backendTarget = new GRBackendTexture(_target.Width, _target.Height, false, fbInfo);
using (_platform.PrimaryEglContext.MakeCurrent())
{
// Here's where we find the gl surface to our texture object apparently.
_platform.PrimaryEglContext.GlInterface.BindTexture(GlConsts.GL_TEXTURE_2D, _glTexHandle[0]);
EglBindTexImage(_angleDisplay.Handle, _glSurface.DangerousGetHandle(), EglConsts.EGL_BACK_BUFFER);
_platform.PrimaryEglContext.GlInterface.BindTexture(GlConsts.GL_TEXTURE_2D, 0);
}
// context is a GRContext
_skiaSurface = SKImage.FromTexture(context, _backendTarget, GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888, SKAlphaType.Premul);
// This clears my render target (obviously). I should be seeing this when I draw the image right?
_target.Clear(GorgonColor.CornFlowerBlue);
canvas.DrawImage(_skiaSurface, new SKPoint(320, 240));
So, as far as I can tell, this should be working. But as I said before, it's only showing me a black image. It's supposed to be cornflower blue. I've tried calling Flush on the ID3D11DeviceContext, but I'm still getting the black image.
Anyone have any idea what I could be doing wrong?
I want to be able to just place a View component (plugin) into the page through code and have it appear at some X\Y on the page... but I'm a bit stumped.
Any attempt to add via page.content kinda adds it to the layout\render pass so it occupies space.
So this would get injected into "any" page at "any" time, I have no control over the markup this would be used in (know what I mean?) There is no XML for it and unfortunately the answer can't just be wrap everything in an AbsoluteLayout because one can't mandate that on users apps\layouts.
Thoughts, even possible?
Basically the simplest way to do this is to dynamically and be fully cross platform compatible is to create a AbsoluteLayout item in your JavaScript code, and dynamically insert your item and the AL into the page container.
Code would be something like this:
var AbsoluteLayout = require('ui/layouts/absolute-layout').AbsoluteLayout;
var myAL = new AbsoluteLayout();
var myItem = new myPluginItem();
// Set you left, right, top, bottom coords.
myItem.top = x;
// Add our item to the AbsoluteItem
myAL.addChild(myItem);
var frame = require('ui/frame');
var page = frame.topmost().currentPage;
var LayoutBase = require('ui/layouts/layout-base').LayoutBase;
page._eachChildView(function(view) {
if (view instanceof LayoutBase) {
view.addChild(myAL);
return false;
}
return true;
});
However, if you don't want to do this the really simple way; the only other way is to actually go a bit lower level. You can natively access the iOS view controller (page._ios.view) and the android view (page._nativeView), and then manually add it to the view by using things like addView (https://developer.android.com/reference/android/view/ViewManager.html) or addSubview (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/).
I would like to add you can set the Top and Left properties in TypeScript by importing AbsoluteLayout like so
import {AbsoluteLayout} from 'ui/layouts/absolute-layout';
and then using the exposed functions setLeft or setTop
AbsoluteLayout.setLeft(YourItem, LeftValue);
or
AbsoluteLayout.setTop(YourItem, TopValue);
I am manually writing some scripts to test a web application with Coded UI. What is the best way to know which HtmlControl tag I should be using for the elements I want to manipulate? For example, how can I easily tell if I should be using HtmlDiv or HtmlSpan, etc? I know that the tag gives a hint, but is there an easier way to do this?
Try using the object recorder that comes with CUITe. That records the object properties for you as well for easy copy/paste.
Use browser development mode (like firebug in Firefox) to identify what is what.
You can also use inspect.exe application (http://msdn.microsoft.com/en-us/library/windows/desktop/dd318521(v=vs.85).aspx) to help with other windows that are not a browser.
Try to extract object information with ExecuteScript method of BrowserWindow
object control = BrowserWindow.ExecuteScript("return $('#yourControlId');");
if your control is of Type HtmlCustom then on hover on return type it will display CustomType[Custom] or CustomType[Span] for HtmlSpan then you can easily cast it to the appropriate control.
If you have only HtmlDiv and HtmlSpan control then you can use generic method as well perform any action on them
protected void PerformAction(object control)
{
object htmlControl = ((List<object>)control)[0];
HtmlDiv htmldiv = htmlControl as HtmlDiv;
HtmlSpan htmlspan = null;
if (htmldiv == null)
{
htmlspan = htmlControl as HtmlSpan ;
if (htmlspan != null){
// Write your action
}
}
if (htmldiv == null && htmlspan == null) return;
// Do your code
}
On hover it you can get your control info as in attached screenshot.
Context:
Silverlight 5, 64 bit, Win7, VS2010
Expected: a new Browser Window/Tab opens up for the url passed in.
Actual: no new browser window ot tab appears.
Code Sample: (called from ViewModel. The View is a sdk:ChildWindow.
AddRelatedIssueDialog dialog = new AddRelatedIssueDialog();
dialog.Closed +=
(s1, e1) =>
{
if (dialog.DialogResult.HasValue && dialog.DialogResult.Value)
{
var window = HtmlPage.PopupWindow("www.goole.com", "_blank", null);
}
};
dialog.Show();
We have also tried Prism events to do the same thing but with no joy...
Also have included the on the control host - but again no luck.
Any help much appreciated:
Cheers,
John
Try this:
HtmlPage.Window.Navigate(new Uri("www.google.com"), "_blank");
It works for me :)