I am using this code to capture screen on iOS but while capturing browser which has YouTube Videos I get black Video
var view = UIApplication.SharedApplication.KeyWindow.RootViewController.View;
UIGraphics.BeginImageContext(view.Frame.Size);
view.DrawViewHierarchy(view.Frame, true);
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
I tried this code to send the webview as a parameter to be captured the view refreshed and the webveiw show progress ring all the time and never reloaded:
public async Task<byte[]> CaptureAsync(Xamarin.Forms.View fView)
{
CGRect rect = new CGRect(fView.X, fView.Y, fView.Height, fView.Width);
var view = ConvertFormsToNative(fView, rect);
UIGraphics.BeginImageContext(view.Frame.Size);
view.DrawViewHierarchy(view.Frame, true);
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
using (var imageData = image.AsPNG())
{
var bytes = new byte[imageData.Length];
System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, bytes, 0, Convert.ToInt32(imageData.Length));
return bytes;
}
}
private UIView ConvertFormsToNative(Xamarin.Forms.View view, CGRect size)
{
var renderer = RendererFactory.GetRenderer(view);
renderer.NativeView.Frame = size;
renderer.NativeView.AutoresizingMask = UIViewAutoresizing.All;
renderer.NativeView.ContentMode = UIViewContentMode.ScaleToFill;
renderer.Element.Layout(size.ToRectangle());
var nativeView = renderer.NativeView;
nativeView.SetNeedsLayout();
return nativeView;
}
It is because you captured the RootViewController.View not the webview or something else.
Just make sure that the view (which you want to convert to screenshot ) is the video view (WebView or WKWebvView or SFSafariViewController.view..)
Related
I have a WebView and i load an image into it. If image is bigger than phone's screen i want to zoom out to have all image on the screen. I do this using WebView.LoadFinished EventHandler. When LoadFinished is triggered i calculate scale to zoom out and set as WebView's MinimumZoomScale and ZoomScale. It works fine but after first zoom in or zoom out image automaticaly zoom in to some specific scale and i can't zoom out. How can i solve it ?
private void InitializeWebView()
{
WebView.ScalesPageToFit = true;
WebView.LoadFinished += WebView_LoadFinished;
}
private void WebView_LoadFinished(object sender, EventArgs e)
{
var contentSize = WebView.ScrollView.ContentSize;
var viewSize = View.Bounds.Size;
var scale = viewSize.Width / contentSize.Width;
WebView.ScrollView.MinimumZoomScale = scale ; //removing this makes that my image doesnt zoom out after loaded
WebView.ScrollView.ZoomScale = scale ;
}
public void LoadAttachment(string fileName)
{
if (string.IsNullOrEmpty(fileName))
{
return;
}
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var targetUrl = documentsPath + "/" + fileName;
var url = new NSUrl(targetUrl);
if (url != null)
{
var request = new NSUrlRequest(url);
WebView.LoadRequest(request);
//Example request: "/var/mobile/Containers/Data/Application/6BDB8CD2-280B-45A3-9109-8E08E1314739/Documents/26112018110204.jpg"
}
}
I try use Lucas Zhang - MSFT's solution like this:
private void WebView_LoadFinished(object sender, EventArgs e)
{
var contentSize = WebView.ScrollView.ContentSize;
var viewSize = View.Bounds.Size;
var scale = viewSize.Width / contentSize.Width;
WebView.ScrollView.MinimumZoomScale = scale;
WebView.ScrollView.ZoomScale = scale;
NSString str = new NSString($"var meta = document.createElement('meta');meta.content='width=device-width,initial-scale={1.0},minimum-scale={scale},maximum-scale={WebView.ScrollView.MaximumZoomScale}';meta.name='viewport';document.getElementsByTagName('head')[0].appendChild(meta);");
WebView.EvaluateJavascript(str);
}
Screenshots:
Image opened
Image scrolled right
Image after first zoom
It is not visible but on the third screenshot there is still posibility to scroll image right. Not all image is on the screen.
Cause:
Because you didn't refer to the tag meta in your html file.
Solution:
Add the following code in the method WebView_LoadFinished
private void WebView_LoadFinished(object sender, EventArgs e)
{
var contentSize = WebView.ScrollView.ContentSize;
var viewSize = View.Bounds.Size;
var scale = viewSize.Width / contentSize.Width;
WebView.ScrollView.MinimumZoomScale = scale ;
WebView.ScrollView.ZoomScale = scale ;
NSString str = new NSString("var meta = document.createElement('meta');meta.content='width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=2.0';meta.name='viewport';document.getElementsByTagName('head')[0].appendChild(meta);");
webView.EvaluateJavascript(str);
}
minimum-scale=1.0,maximum-scale=2.0
You can set the value of MinimumZoomScale and MaximumZoomScale here.
I am trying to use PDF.js to view PDF documents. I find the display really low resolutions to the point of being blurry. Is there a fix?
// URL of PDF document
var url = "https://www.myFilePath/1Mpublic.pdf";
// Asynchronous download PDF
PDFJS.getDocument(url)
.then(function(pdf) {
return pdf.getPage(1);
})
.then(function(page) {
// Set scale (zoom) level
var scale = 1.2;
// Get viewport (dimensions)
var viewport = page.getViewport(scale);
// Get canvas#the-canvas
var canvas = document.getElementById('the-canvas');
// Fetch canvas' 2d context
var context = canvas.getContext('2d');
// Set dimensions to Canvas
canvas.height = viewport.height;
canvas.width = viewport.width;
// Prepare object needed by render method
var renderContext = {
canvasContext: context,
viewport: viewport
};
// Render PDF page
page.render(renderContext);
});
There are two things you can do. I tested and somehow it worked, but you will get a bigger memory consumption.
1 . Go to pdf.js and change the parameter MAX_GROUP_SIZE to like 8192 (double it for example) . Be sure to have your browser cache disable while testing.
You can force the getViewport to retrieve the image in better quality but like, I don't know how to say in English, compress it so a smaller size while showing:
// URL of PDF document
var url = "https://www.myFilePath/1Mpublic.pdf";
// Asynchronous download PDF
PDFJS.getDocument(url)
.then(function(pdf) {
return pdf.getPage(1);
})
.then(function(page) {
// Set scale (zoom) level
var scale = 1.2;
// Get viewport (dimensions)
var viewport = page.getViewport(scale);
// Get canvas#the-canvas
var canvas = document.getElementById('the-canvas');
// Fetch canvas' 2d context
var context = canvas.getContext('2d');
// Set dimensions to Canvas
var resolution = 2 ; // for example
canvas.height = resolution*viewport.height; //actual size
canvas.width = resolution*viewport.width;
canvas.style.height = viewport.height; //showing size will be smaller size
canvas.style .width = viewport.width;
// Prepare object needed by render method
var renderContext = {
canvasContext: context,
viewport: viewport,
transform: [resolution, 0, 0, resolution, 0, 0] // force it bigger size
};
// Render PDF page
page.render(renderContext);
});
enter code here
Hope it helps!
This code will help you, my issue was pdf was not rendering in crisp quality according with the responsiveness. So i searched , and modified my code like this. Now it works for rendering crisp and clear pdf according to the div size you want to give. `var loadingTask = pdfjsLib.getDocument("your_pdfurl");
loadingTask.promise.then(function(pdf) {
console.log('PDF loaded');
// Fetch the first page
var pageNumber = 1;
pdf.getPage(pageNumber).then(function(page) {
console.log('Page loaded');
var container = document.getElementById("container") //Container of the body
var wrapper = document.getElementById("wrapper");//render your pdf inside a div called wrapper
var canvas = document.getElementById('pdf');
var context = canvas.getContext('2d');
const pageWidthScale = container.clientWidth / page.view[2];
const pageHeightScale = container.clientHeight / page.view[3];
var scales = { 1: 3.2, 2: 4 },
defaultScale = 4,
scale = scales[window.devicePixelRatio] || defaultScale;
var viewport = page.getViewport({ scale: scale });
canvas.height = viewport.height;
canvas.width = viewport.width;
var displayWidth = Math.min(pageWidthScale, pageHeightScale);;
canvas.style.width = `${(viewport.width * displayWidth) / scale}px`;
canvas.style.height = `${(viewport.height * displayWidth) / scale}px`;
// Render PDF page into canvas context
var renderContext = {
canvasContext: context,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function() {
console.log('Page rendered');
});
});
}, function(reason) {
// PDF loading error
console.error(reason);
});`
I've got an image that im trying to add to the current camera location of the Screenview ARSCNView session. Whatever I do it seems to put the image behind the current location of the phone camera and i have to move it back to see it. I have the following code:
var currentFrame = SceneView.Session.CurrentFrame;
if (currentFrame == null) return;
var threeVector = new SCNVector3(currentFrame.Camera.Transform.Column3.X + 0.005f,
currentFrame.Camera.Transform.Column3.Y - 0.02f,
currentFrame.Camera.Transform.Column3.Z - 0.05f);
var scaleFactor = imgToAdd.Size.Width / 0.05;
float width = float.Parse((imgToAdd.Size.Width / scaleFactor).ToString());
float height = float.Parse((imgToAdd.Size.Height / scaleFactor).ToString());
var box = new SCNPlane {
Width = width,
Height = height
};
var cubeNode = new SCNNode {
Position = threeVector,
Geometry = box
};
var mat = new SCNMaterial();
mat.Diffuse.Contents = imgToAdd;
mat.LocksAmbientWithDiffuse = true;
cubeNode.Geometry.Materials = new[] { mat };
SceneView.Scene.RootNode.AddChildNode(cubeNode);
Just trying to execute a simple idea of the ARKit paint apps that you see all over the app store now. So the imgToAdd is a snapshot of the scribble that the user has already put onto the screen and this event is fired at the touchended after an image is created from the view scribbled on.
Any ideas on what I need to change to get it to line up with the current view of the camera on the phone?
I am trying to create a app that uses skiasharp on an overlay for the camera on iPhone (native). My camera stream appears nicely but no overlay. the initial viewcontroller that creates the stream looks like:
public async override void ViewDidLoad()
{
base.ViewDidLoad();
await AuthorizeCameraUse();
imagePicker = new UIImagePickerController();
// set our source to the camera
imagePicker.SourceType = UIImagePickerControllerSourceType.Camera;
// set
imagePicker.MediaTypes = new string[] { "public.image" };
imagePicker.CameraOverlayView = new CameraOverlayView();
imagePicker.ModalPresentationStyle = UIModalPresentationStyle.CurrentContext;
. . .
my CameraOverlayView looks like:
public class CameraOverlayView :SKCanvasView
{
public CameraOverlayView() : base()
{
Initialize();
}
public CameraOverlayView(CGRect frame) : base(frame) {
Initialize();
}
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Fill,
Color = SKColors.Red,
StrokeWidth = 25
};
protected void Initialize()
{
this.PaintSurface += CameraOverlayView_PaintSurface;
//using (var surface = SKSurface.Create( 640, 480, SKColorType.Rgba8888, SKAlphaType.Premul))
//{
// SKCanvas myCanvas = surface.Canvas;
// myCanvas.DrawCircle(300, 300, 100, paint);
// // Your drawing code goes here.
//}
}
private void CameraOverlayView_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
var surface = e.Surface;
// then we get the canvas that we can draw on
var canvas = surface.Canvas;
// clear the canvas / view
canvas.Clear(SKColors.White);
// DRAWING SHAPES
// create the paint for the filled circle
var circleFill = new SKPaint
{
IsAntialias = true,
Style = SKPaintStyle.Fill,
Color = SKColors.Blue
};
// draw the circle fill
canvas.DrawCircle(100, 100, 40, circleFill);
}
}
my Paint event is never fired , if I run this code in simple example it does.
thanks to Russ Fustino help it turns out I was not using the CameraOverlayView (CGRect frame) : base (frame) constructor and because of that the DrawInSurface overload is not called.
Nothing to draw into. when I did this the paint event fired.
I am trying to save a screenshot of a chart using xamarin. Everything is fine, except that there are times that the chart is wider than the frame, and the user needs to scroll - saving a screenshot of this gives me a truncated chart. Been scratching my head on this for almost 2 days now, below is the code. Hope anyone can point me to something.
UIImage image;
UIGraphics.BeginImageContext (UIScreen.MainScreen.ApplicationFrame.Size);
View.DrawViewHierarchy (View.Frame, true);
image = UIGraphics.GetImageFromCurrentImageContext ();
UIGraphics.EndImageContext ();
image.SaveToPhotosAlbum((img, err) => {
...
});
try use a function like this:
public UIImage SnapshotImageWithCrop (UIView view, float locHorizontal, float locVertical, float widthSize, float heightSize)
{
UIGraphics.BeginImageContext (view.Frame.Size);
view.DrawViewHierarchy (view.Frame, true);
UIImage image = UIGraphics.GetImageFromCurrentImageContext ();
UIGraphics.EndImageContext ();
UIImage croppedImage;
using (CGImage cr = image.CGImage.WithImageInRect (new RectangleF (locHorizontal, locVertical, widthSize, heightSize))) {
croppedImage = UIImage.FromImage (cr);
}
return croppedImage;
}