samsung prime pantalla pagina online lightshot hacer completa como chrome capturar captura c# .net winapi selenium screenshot

c# - prime - lightshot



La mejor manera de hacer una captura de pantalla de una página web. (5)

He estado usando webshotcmd (la versión de pago también es línea de comandos) en una aplicación de producción durante años. Puede configurarse para esperar a que se cargue la página, para esperar n segundos después de la carga de la página, etc. Utiliza Internet Explorer y funciona en Windows. Comienza bastante rápido (en mi experiencia, el msie activex siempre ha sido instantáneo para cargar).

Aparte de lo anterior, recomendaría algo basado en una biblioteca de Webkit, sería mucho más pequeño que Firefox y comenzaría muy rápido (por el momento, wkhtmltoimage solo está disponible en Linux, pero cuando esté disponible para Windows, lo haría). Ve por ello - también línea de comando). En este momento solo google para la captura de pantalla de webkit (la gran cantidad de capturas de pantalla disponibles que usan webkit me hace creer que usar esa DLL sería fácil de portar a C #).

Edición: considerando su segunda edición, eche un vistazo a la fuente de captura de pantalla de Chrome . Para probarlo, la extensión está disponible en la tienda / galería de extensiones.

¿Cuál es la mejor manera de tomar una captura de pantalla de una página web? En este momento acabo de iniciar una instancia de selenio de Firefox y, con Winapi, llevarlo al frente y hacer una captura de pantalla. Ya hago una question similar.

Hay dos puntos:

  • Lentitud.
  • Si alguna ventana llega a ser más alta que la ventana de nuestro navegador web, esta ventana se imprimirá en nuestra captura de pantalla.

¿Hay algún método para tomar la captura de pantalla más ''programmly''?

Aquí hay un código que uso ahora:

class FirefoxDriverEx : FirefoxDriver { public Process GetFirefoxProcess() { var fi = typeof(FirefoxBinary).GetField("process", BindingFlags.NonPublic | BindingFlags.Instance); return fi.GetValue(this.Binary) as Process; } }

Aquí está el código que ilustra el proceso de tomar una captura de pantalla:

using (FirefoxDriverEx driver = new FirefoxDriverEx()) { driver.Navigate().GoToUrl(url); var process = driver.GetFirefoxProcess(); if (process != null) { var screenCapture = new ScreenCapture(); Win.SetForegroundWindow(process.MainWindowHandle.ToInt32()); } }

En este momento, estoy pensando en algún administrador que controle una cola de ventanas para tomar las capturas de pantalla.

Edición de la pregunta.

No estoy buscando una solución para obtener la captura de pantalla ''en la memoria'' y devolverla a la secuencia HTTP. Así que cualquier forma de guardar la captura de pantalla y guardarlo en un archivo y luego obtenerlo desde allí es muy ambiguo para ese propósito.

Edición de la pregunta # 2.

Me olvidé de mencionar. Captura de pantalla necesaria debe hacerse como lo ve el usuario. Por lo tanto, la captura de pantalla debe tener una ventana del navegador y un sitio dentro de los límites de la ventana del navegador web. No puedo encontrar ninguna manera de cambiar el modo de tomar una captura de pantalla en WebDriver of selenium. WebDriver simplemente toma la captura de pantalla de una página sin ninguna ventana del navegador.


Pude lograr esto copiando la ventana (pieza por pieza) en un mapa de bits que se establece en el tamaño del ScrollRectangle para mi control webBrowser. Si bien ciertamente no es la forma más elegante de lograr este objetivo, quería compartir el código en caso de que alguien pudiera usarlo. Una vez que tuve algo que funcionaba en su mayoría, pude agregar algunos argumentos y ahora puedo ejecutar esta utilidad desde la línea de comandos:

Nombre de archivo de URL de Executable_Path

/// <summary> /// This method is called to start the process of copying the webpage to the bitmap /// this should be called after the page has fully loaded (use DocumentCompleted event to determine /// if the page has completed loading if calling from the command line.) /// </summary> private void copyWebpageToImage() { //these two vars will house the current position in the bmp file (starting at 0,0) int currXPosition = 0; int currYPosition = 0; //we need to set the height and width of our bitmap to the scrollrectangle of the webbrowser document object int width = webBrowser1.Document.Body.ScrollRectangle.Width; int height = webBrowser1.Document.Body.ScrollRectangle.Height; //instantiate the bitmap bm = new Bitmap(wd, ht); //Instantiate our graphics object Graphics gfx = Graphics.FromImage((Image)bm); //this point is used throughout the process, and helps to determine where the form is at on the screen Point formPoint = Form1.ActiveForm.Location; formPoint.X = formPoint.X + webBrowser1.Location.X; formPoint.Y = formPoint.Y + webBrowser1.Location.Y; formPoint.X = formPoint.X + 8; //offsets for my form (may be different for yours) formPoint.Y = formPoint.Y + 33; //offsets for my form //begin our recursive call that will stop when it reaches the end of the page copyEverythingToBitmap(bm, currXPosition, currYPosition, formPoint, gfx); } private void copyEverythingToBitmap(Bitmap bm, int currXPosition, int currYPosition, Point formPoint, Graphics gfx) { //check to see if currXPosition and currYPosition are both 0, if so we just began, call the zero copy method if (currXPosition == 0 && currYPosition == 0) { performZeroCopy(bm, currXPosition, currYPosition, formPoint, gfx); } //if the current x position is less than the total width of the scrollrectangle - the width of the webbrowser, //then we need to scroll the window, and copy the contents, y stays the same else if (currXPosition < bm.Width - webBrowser1.Width) { AlterXPosition(bm, ref currXPosition, ref currYPosition, ref formPoint, gfx); } //if we are no longer at the zero, zero, and we cannot increase the x position anymore, //then we need to scroll the window down and copy the contents, x is reset back to zero else if(currYPosition < bm.Height - webBrowser1.Height) { currYPosition = currYPosition + webBrowser1.Height - 20; currXPosition = 0; performZeroCopy(bm, currXPosition, currYPosition, formPoint, gfx); } } /// <summary> /// The name of this method is slightly misleading. It inherently means that X is zero. /// </summary> private void performZeroCopy(Bitmap bm, int currXPosition, int currYPosition, Point formPoint, Graphics gfx) { webBrowser1.Document.Window.ScrollTo(currXPosition, currYPosition); gfx.CopyFromScreen(formPoint, new Point(currXPosition, currYPosition), new Size(webBrowser1.Width - 20, webBrowser1.Height - 20)); if (currXPosition < bm.Width - webBrowser1.Width) { AlterXPosition(bm, ref currXPosition, ref currYPosition, ref formPoint, gfx); } else if(currYPosition < bm.Height - webBrowser1.Height) { currYPosition = currYPosition + webBrowser1.Height - 20; currXPosition = 0; performZeroCopy(bm, currXPosition, currYPosition, formPoint, gfx); } } private void AlterXPosition(Bitmap bm, ref int currXPosition, ref int currYPosition, ref Point formPoint, Graphics gfx) { currXPosition = currXPosition + webBrowser1.Width - 20; webBrowser1.Document.Window.ScrollTo(bm.Width - currXPosition, currYPosition); gfx.CopyFromScreen(formPoint, new Point(bm.Width - currXPosition - 3, currYPosition), new Size(webBrowser1.Width - 20, webBrowser1.Height - 20)); if (currXPosition + webBrowser1.Width < bm.Width) { //we still have not traversed the full width of the page, call to alterxposition again... } else { copyEverythingToBitmap(bm, currXPosition, currYPosition, formPoint, gfx); } } private void saveImageToFile(string p) { bm.Tag = DateTime.Now; bm.Save(p, ImageFormat.Jpeg); }


Recomiendo getScreenshotAs. Obtiene incluso la parte ''fuera de la vista'' de la pantalla.

Aquí hay un código de ejemplo en gr0ovy.

import java.io.IOException import java.net.URL import java.nio.file.Path import java.nio.file.Paths import java.text.SimpleDateFormat import org.openqa.selenium.Capabilities import org.openqa.selenium.TakesScreenshot import org.openqa.selenium.WebDriverException import org.openqa.selenium.remote.CapabilityType import org.openqa.selenium.remote.DriverCommand import org.openqa.selenium.remote.RemoteWebDriver import org.openqa.selenium.OutputType import org.openqa.selenium.WebDriver public class Selenium2Screenshot { private WebDriver driver private String browserType private boolean skipScreenshots public Selenium2Screenshot(WebDriver webDriver, String browserType, boolean skipScreenshots) { this.driver = webDriver this.browserType = browserType this.skipScreenshots = skipScreenshots } public void takeScreenshot(String filenameBase) { if (!skipScreenshots) { Date today String formattedDate SimpleDateFormat formatter Locale currentLocale File scrFile currentLocale = new Locale("en", "US") formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS", currentLocale) today = new Date() formattedDate = formatter.format(today) String filename = getUiAutomationDir() + filenameBase + "_" + browserType + formattedDate + ".png" Log.logger.info("Screenshot filename = " + filename) try { scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE) JavaIO.copy(scrFile.getAbsolutePath(), filename) } catch (Exception e) { Log.logger.error(e.message, e) } } else { Log.logger.info("Skipped Screenshot") } } private String getUiAutomationDir() { String workingDir = System.getProperty("user.dir") Path workingDirPath = Paths.get(workingDir) String returnString = workingDirPath.toString() + "//" return returnString }

}

Editado el 01/08/12:

Obtener el código de manejo de la aplicación. Seguramente estoy duplicando el código que está en varias veces, pero espero que este no sea exactamente el mismo código que en otras publicaciones :-)

public static IntPtr FindWindowByPartialCaption(String partialCaption) { var desktop = User32.GetDesktopWindow(); var children = EnumerateWindows.GetChildWindows(desktop); foreach (var intPtr in children) { var current = GetText(intPtr); if (current.Contains(partialCaption)) return intPtr; } return IntPtr.Zero; } [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")] public static extern IntPtr GetDesktopWindow(); [DllImport("user32.dll")] public static extern bool EnumChildWindows(IntPtr hWndParent, EnumWindowProc lpEnumFunc, IntPtr lParam); public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter); public static List<IntPtr> GetChildWindows(IntPtr parent) { return GetChildWindows(parent, false); } public static List<IntPtr> GetChildWindows(IntPtr parent, bool reverse) { List<IntPtr> result = new List<IntPtr>(); GCHandle listHandle = GCHandle.Alloc(result); try { EnumWindowProc childProc = new EnumWindowProc(EnumWindow); EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle)); } finally { if (listHandle.IsAllocated) listHandle.Free(); } if (reverse) { List<IntPtr> resultList = result.Reverse<IntPtr>().ToList(); return resultList; } else return result; } private static bool EnumWindow(IntPtr handle, IntPtr pointer) { GCHandle gch = GCHandle.FromIntPtr(pointer); List<IntPtr> list = gch.Target as List<IntPtr>; if (list == null) { throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>"); } list.Add(handle); // You can modify this to check to see if you want to cancel the operation, then return a null here return true; } }

http://www.pinvoke.net/ también es un gran recurso.


Si está buscando una forma programática de obtener una captura de pantalla de la ventana principal de un proceso dado, aquí hay una función que lo hace:

public static Bitmap TakeScreenshot(Process process) { // may need a process Refresh before return TakeScreenshot(process.MainWindowHandle); } public static Bitmap TakeScreenshot(IntPtr handle) { RECT rc = new RECT(); GetWindowRect(handle, ref rc); Bitmap bitmap = new Bitmap(rc.right - rc.left, rc.bottom - rc.top); using (Graphics graphics = Graphics.FromImage(bitmap)) { PrintWindow(handle, graphics.GetHdc(), 0); } return bitmap; } [DllImport("user32.dll")] private static extern bool GetWindowRect(IntPtr hWnd, ref RECT rect); [DllImport("user32.dll")] private static extern bool PrintWindow(IntPtr hWnd, IntPtr hDC, int flags); [StructLayout(LayoutKind.Sequential)] private struct RECT { public int left; public int top; public int right; public int bottom; }

Desafortunadamente, en el sistema operativo equipado con Aero (Vista / Win7 / Win8) no capturará el borde transparente completo. El borde transparente habitual se oscurecerá en su lugar. Tal vez sea suficiente para lo que estás tratando de lograr.


http://msdn.microsoft.com/en-us/library/windows/desktop/dd162869(v=vs.85).aspx

Personalmente me encanta esta API. Cree un mapa de bits con el ancho y la altura calculados a partir del rectángulo devuelto de la API GetWindowRect y para el uso del parámetro HDC (por ejemplo):

thebitmap.GetHdc()

Deberías estar bien.

Edición: también compruebe this .

Por cierto, puedes tomar una captura de pantalla de cualquier ventana que desees, incluso si se caen hacia atrás. (Ten en cuenta que esto no funcionará con ventanas minimizadas. Sin embargo, si realmente lo necesitas, también hay algunas opciones para eso).