ios - Taking screenshot of WKWebview with hardware accelerated content -
i having serious trouble taking screenshot of wkwebview content when there hardware accelerated content (some specific casino games running inside iframe). far used standard way of taking screenshot suggests:
uigraphicsbeginimagecontextwithoptions(containerview.frame.size, true, 0.0) containerview.layer.render(in: uigraphicsgetcurrentcontext()!) //this line helps fix view rendering taking screenshot on older ios devices containerview.drawhierarchy(in: containerview.bounds, afterscreenupdates: true) let image = uigraphicsgetimagefromcurrentimagecontext()! uigraphicsendimagecontext()
this method works nicely until content inside wkwebview rendered gpu. gpu rendered content appears black on screenshot. tried tricks possible method nothing helps. xcode view hierarchy debugger cant show hardware accelerated content. therefore, similar android, i need way take screenshot. i solved similar problem on android starting record happening on screen , stopping screen record after got first image.
i have went through numerous stack overflow questions , solutions in obj-c (which totally suck at), outdated or not specific enough needs.
now found out, can use glreadpixels read pixels right out opengl (if content hardware accelerated make sense can read pixels graphics card then, right ??)
so far have managed create swift snippet renderbuffer -> framebuffer -> glreadpixels -> image
let width = int(containerview.frame.size.width) let height = int(containerview.frame.size.height) //beginimagecontext code run above let api = eaglrenderingapi.opengles3 let context2 = eaglcontext(api: api) eaglcontext.setcurrent(context2) // setup render buffer var renderbuffer : gluint = gluint() let size = glsizei(10) glgenrenderbuffers(size, &renderbuffer) glbindrenderbuffer(glenum(gl_renderbuffer), renderbuffer) let bufferwidth = glsizei(width * 1) let bufferheight = glsizei(height * 1) let bufferformat = glenum(gl_rgba8) glrenderbufferstorage(glenum(gl_renderbuffer), bufferformat, bufferwidth, bufferheight) // setup frame buffer var framebuffer = gluint() glgenframebuffers(glsizei(10), &framebuffer) glbindframebuffer(glenum(gl_framebuffer), framebuffer) glframebufferrenderbuffer(glenum(gl_framebuffer), glenum(gl_color_attachment0), glenum(gl_renderbuffer), renderbuffer) // draw glreadbuffer(glenum(gl_renderbuffer)) glclearcolor(0.1, 0.2, 0.3, 0.2) glclear(glbitfield(gl_color_buffer_bit)) //-------------- let bytes = malloc(width*height*4) let bytes2 = malloc(width*height*4) let x : glint = glint(0) let y : glint = glint(0) let w : glsizei = glsizei(width) let h : glsizei = glsizei(height) glreadpixels(x, y, w, h, glenum(gl_rgba), glenum(gl_unsigned_byte), bytes) let data = nsdata(bytes: bytes, length: width * height * 4) let dataprovider = cgdataprovider(data: data) //let dataprovider2 = cgdataprovider(datainfo: nil, data: bytes!, size: width * height * 4, releasedata: ) let colorspace = cgcolorspacecreatedevicergb() let bitmapinfo: cgbitmapinfo = [.byteorder32little, cgbitmapinfo(rawvalue: cgimagealphainfo.last.rawvalue)] let acgimage = cgimage( width: int(width), height: int(height), bitspercomponent: 8, bitsperpixel: 32, bytesperrow: 4 * int(width), space: colorspace, bitmapinfo: bitmapinfo, provider: dataprovider!, decode: nil, shouldinterpolate: true, intent: .defaultintent )! let imaag = uiimage(cgimage: acgimage) //i image of same color defined @ clearcolor
now question is, going right way? possible can wkwebview (or take snapshot of , make uiview) somehow renderbuffer / framebuffer glreadpixels read on screen?
ps! have seen numerous questions getting uiimage out of caeaglview, in case, not caeglview wkwebview instead. appreciated.
Comments
Post a Comment