Xamarin Maps on android custom pins query - xamarin.forms

I am working on a xamarin forms app using xamarin forms maps for Android at the moment that tracks my location and depending on my proximity to a custom pin i have placed on the map will change in size depending on my proximity.
Basically if within a few meters the icon is 32x32 and farther away its 24x24.
Ive created a custom map renderer that places my pins from a JSON file and this is ok.
When my map form page loads in both my simulator and an actual android device the methods run and get my proximity based on my location and appropriately alter the size of the map pin.
However, this does not work as i move around.
For some reason my overridden CreateMarker method does not trigger when my location changes unless i call Content=customMap. Doing this only causes my map to load over and over and basically will not work.
I have a method in my about page called UpdateMap3() that is called when the users location changes. However, as stated i cant get the pins to update their size as i get nearer the pins while the app is running.
Ive included my forms page code behind below and markup below that and finally my map renderer below that.
Any help would be hugely appreciated.
Thanls
using System;
using System.IO;
using System.Reflection;
using Xamarin.Forms;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Xamarin.Forms.Maps;
using Xamarin.Essentials;
using Distance = Xamarin.Forms.Maps.Distance;
using Google.Protobuf.WellKnownTypes;
using static Google.Protobuf.Reflection.FieldDescriptorProto.Types;
namespace MAPS.Views
{
public partial class AboutPage : ContentPage
{
IlocationUpdateService loc;
public AboutPage()
{
InitializeComponent();
// Task.Delay(2000);
UpdateMap();
}
async void OnActionSheetCancelDeleteClicked()
{
bool answer = await DisplayAlert("Location Request", "Please enable location services to use this app", "Settings", "Cancel");
if (answer == true)
{
DependencyService.Get<ILocSettings>().OpenSettings();
}
}
protected override void OnAppearing()
{
base.OnAppearing();
bool gpsStat = DependencyService.Get<ILocSettings>().isGpsAvailable();
if (gpsStat == false)
{
OnActionSheetCancelDeleteClicked();
}
loc = DependencyService.Get<IlocationUpdateService>();
loc.LocationChanged += (object sender, ILocationEventArgs args) =>
{
String lat1 = args.Latitude.ToString();
String lng1 = args.Longitude.ToString();
//String lat1 = "55.099300";
// String lng1 = "-8.279740";
UpdateMap3(lat1, lng1); ;
};
loc.GetUsedLocation();
}
protected override void OnDisappearing()
{
base.OnDisappearing();
loc = null;
}
List<Place> placesList = new List<Place>();
private async void UpdateMap()
{
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(AboutPage)).Assembly;
Stream stream = assembly.GetManifestResourceStream("MAPS.Places.json");
string text = string.Empty;
using (var reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
var resultObject = JsonConvert.DeserializeObject<Places>(text);
var request = new Xamarin.Essentials.GeolocationRequest(GeolocationAccuracy.Best, TimeSpan.FromSeconds(30));
var location = await Geolocation.GetLocationAsync(request);
CustomMap customMap = new CustomMap()
{
IsShowingUser = true
};
customMap.CustomPins = new List<CustomPin>(); // put this before the foreach
foreach (var place in resultObject.results)
{
Location location1 = new Location(place.geometry.location.lat,place.geometry.location.lng);
// string color = getDist(location1, location);
string color = "purple";
if (color == "purple")
{
CustomPin pin = new CustomPin()
{
Type = PinType.Place,
Position = new Position(place.geometry.location.lat, place.geometry.location.lng),
Label = place.id,
Address = place.vicinity+"*",
Name = "Xamarin",
icon = "icon.png",
Url = "http://xamarin.com/about/"
};
customMap.Pins.Add(pin);
}
else
{
CustomPin pin = new CustomPin()
{
Type = PinType.Place,
Position = new Position(place.geometry.location.lat, place.geometry.location.lng),
Label = place.id,
Address = place.vicinity,
Name = "Xamarin",
icon = "pin.png",
Url = "http://xamarin.com/about/"
};
customMap.Pins.Add(pin);
}
}
customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(location.Latitude, location.Longitude), Distance.FromKilometers(0.15))); ;
Content = customMap;
}
public string getDist(Location loc, Xamarin.Essentials.Location currentLoc)
{
string color = "red";
// bool geo = false;
double latEnd = loc.lat;
double lngEnd = loc.lng;
/// Position(currentLoc.lat, currentLoc.lng);
double dist = currentLoc.CalculateDistance(latEnd, lngEnd, DistanceUnits.Kilometers);
if (dist < 0.05) //5m distance
{
color = "purple";
}
else
{
color = "red";
}
return color;
}
public void getNewPins()
{
InitializeComponent();
}
public void getPin()
{
var pr = new PopUp();
}
private async void UpdateMap3(String lat, String lng)
{
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(AboutPage)).Assembly;
Stream stream = assembly.GetManifestResourceStream("MAPS.Places.json");
string text = string.Empty;
using (var reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
var resultObject = JsonConvert.DeserializeObject<Places>(text);
CustomMap customMap = new CustomMap()
{
IsShowingUser = true
};
customMap.CustomPins = new List<CustomPin>(); // put this before the foreach
foreach (var place in resultObject.results)
{
Location location1 = new Location(place.geometry.location.lat, place.geometry.location.lng);
Xamarin.Essentials.Location location = new Xamarin.Essentials.Location(Convert.ToDouble(lat), Convert.ToDouble(lng));
string color = getDist(location1, location);
if (color == "purple")
{
CustomPin pin2 = new CustomPin()
{
Type = PinType.Place,
Position = new Position(place.geometry.location.lat, place.geometry.location.lng),
Label = place.id,
Address = place.vicinity,
Name = "Xamarin",
icon = "icon.png",
Url = "http://xamarin.com/about/"
};
customMap.CustomPins = new List<CustomPin> {pin2};
customMap.Pins.Add(pin2);
}
else
{
CustomPin pin2 = new CustomPin()
{
Type = PinType.Place,
Position = new Position(place.geometry.location.lat, place.geometry.location.lng),
Label = place.id,
Address = place.vicinity+"*",
Name = "Xamarin",
icon = "pin.png",
Url = "http://xamarin.com/about/"
};
customMap.CustomPins = new List<CustomPin> { pin2 };
customMap.Pins.Add(pin2);
// Content.IsEnabled = true;
// customMap.CustomPins.Remove(pin);
}
}
// customMap.Pins.Clear();
// customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(Convert.ToDouble(lat), Convert.ToDouble(lng)), Distance.FromKilometers(0.15))); ;
// Content = customMap;
// customMap.Pins.Add(pins);
}
}
}
Below is my forms page markup.
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MAPS;assembly=MAPS"
x:Class="MAPS.Views.AboutPage" Title="Explore">
<StackLayout>
<local:CustomMap x:Name="customMap" IsShowingUser="True"
MapType="Street" />
</StackLayout>
</ContentPage>
Below is my Android custom renderer
using Android.Content;
using Android.Gms.Maps;
using Android.Gms.Maps.Model;
using Android.Widget;
using MAPS;
using MAPS.Droid;
using MAPS.Views;
using Newtonsoft.Json;
using Rg.Plugins.Popup;
using Rg.Plugins.Popup.Animations;
using Rg.Plugins.Popup.Contracts;
using Rg.Plugins.Popup.Enums;
using Rg.Plugins.Popup.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Maps.Android;
using static MAPS.Droid.CustomMapRenderer;
[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace MAPS.Droid
{
public class CustomMapRenderer : Xamarin.Forms.Maps.Android.MapRenderer, GoogleMap.IInfoWindowAdapter
{
List<CustomPin> customPins;
public string popInfo;
public CustomMapRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Map> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
NativeMap.InfoWindowClick -= OnInfoWindowClick;
}
if (e.NewElement != null)
{
var formsMap = (CustomMap)e.NewElement;
customPins = formsMap.CustomPins;
Control.GetMapAsync(this);
}
}
protected override void OnMapReady(GoogleMap map)
{
base.OnMapReady(map);
NativeMap.InfoWindowClick += OnInfoWindowClick;
NativeMap.SetInfoWindowAdapter(this);
}
protected override MarkerOptions CreateMarker(Pin pin)
{
var marker = new MarkerOptions();
// CustomPin p = new CustomPin();
//foreach (var cp in customPins)
//{
// if (cp.Position == pin.Position)
// {
// p = cp;
// }
//}
marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
marker.SetTitle(pin.Label);
// marker.SetIcon(BitmapDescriptorFactory.FromFile(p.icon));
if (pin.Address.Contains('*'))
{
marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin2));
}
else
{
marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin));
}
marker.Visible(true);
var a = NativeMap.AddMarker(marker);
a.ShowInfoWindow();
// marker.SetSnippet(pin.Address.Replace("*", " "));
return marker;
}
void OnInfoWindowClick(object sender, GoogleMap.InfoWindowClickEventArgs e)
{
getPlaceData(markerdata.markerData.title, markerdata.markerData.lat, markerdata.markerData.lng);
showPopUp();
}
public Android.Views.View GetInfoContents(Marker marker)
{
return null;
}
public void myMod(Marker marker)
{
}
public Android.Views.View GetInfoWindow(Marker marker)
{
markerdata.markerData.title = marker.Title;
markerdata.markerData.lat = marker.Position.Latitude.ToString("0.#####");
markerdata.markerData.lng = marker.Position.Longitude.ToString("0.#####");
// ds.Id = marker.Id;
// getPlaceData(marker.Title, marker.Position.Latitude.ToString("0.#####"), marker.Position.Longitude.ToString("0.#####"));
// showPopUp();
return null;
}
public string Number;
private async void showPopUp()
{
var Pr = new Views.PopUp();
var scaleAnimation = new ScaleAnimation
{
PositionIn = MoveAnimationOptions.Right,
PositionOut = MoveAnimationOptions.Left
};
Pr.Animation = scaleAnimation;
await PopupNavigation.PushAsync(Pr);
}
CustomPin GetCustomPin(Marker annotation)
{
return null;
}
private void getPlaceData(String name, String Lat, String Lng)
{
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(AboutPage)).Assembly;
Stream stream = assembly.GetManifestResourceStream("MAPS.Places.json");
string text = string.Empty;
using (var reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
var resultObject = JsonConvert.DeserializeObject<Places>(text);
foreach (var place in resultObject.results)
{
if((name==place.id)&&(Lat ==place.geometry.location.lat.ToString("0.#####"))&&(Lng ==place.geometry.location.lng.ToString("0.#####")))
{
getData.Instance.Id = place.id;
getData.Instance.lat = place.geometry.location.lat.ToString("0.#####");
getData.Instance.lng = place.geometry.location.lng.ToString("0.#####");
getData.Instance.marker2 = place.name;
getData.Instance.family = place.family;
getData.Instance.origin = place.Origin;
getData.Instance.date = place.Date;
getData.Instance.commonName = place.CommonName;
// getData.Instance.title = marker.Title;
}
}
}
}
}

Related

How do I use FirebaseAdmin with proxy?

Following code is working locally very fine.
The users receive All pushes (notifications) when I send them via local PC.
But I need use proxy on the server and this code fires the error: "Failed to establish a connection: Network is unreachable".
Plz help me setup the proxy for this code.
using System;
using MediatR;
using System.IO;
using FirebaseAdmin;
using System.Threading;
using System.Threading.Tasks;
using FirebaseAdmin.Messaging;
using Google.Apis.Auth.OAuth2;
namespace JMGlobal.Handlers
{
public class PushHandler : IRequestHandler<Request_Push, Response_Push>
{
public async Task<Response_Push> Handle(Request_Push request, CancellationToken cancellationToken)
{
try
{
var defaultApp = FirebaseApp.DefaultInstance;
if (defaultApp == null)
{
var keyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "jKey.json");
defaultApp = FirebaseApp.Create(new AppOptions()
{
Credential = GoogleCredential.FromFile(keyPath),
// HttpClientFactory --- ????
});
}
var message = new Message()
{
Token = request.FirebaseToken,
Apns = new ApnsConfig()
{
Aps = new FirebaseAdmin.Messaging.Aps()
{
Alert = new ApsAlert()
{
Title = "push",
Body = request.PushMessage
}
}
},
Notification = new Notification
{
Title = "System Notification",
Body = $"Message: {request.PushMessage}"
}
};
var messaging = FirebaseMessaging.DefaultInstance;
var result = await messaging.SendAsync(message); // here fires the error: "Failed to establish a connection: Network is unreachable"
return new Response_Push()
{ .... };
}
catch (Exception ex)
{..... }
}
}
}
Working version below.
using System;
using MediatR;
using System.IO;
using FirebaseAdmin;
using System.Threading;
using System.Diagnostics;
using System.Threading.Tasks;
using FirebaseAdmin.Messaging;
using Google.Apis.Auth.OAuth2;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Google.Apis.Http;
using System.Net.Http;
using System.Net;
using Microsoft.Extensions.Options;
namespace JMGlobal.Handlers
{
public class ProxyHttpClientFactory2 : Google.Apis.Http.HttpClientFactory
{
private readonly string proxyAddress;
private readonly bool proxyUseProxy;
private readonly bool proxyBypassOnLocal;
public ProxyHttpClientFactory2(string proxyAddress, bool proxyUseProxy, bool proxyBypassOnLocal)
{
this.proxyAddress = proxyAddress;
this.proxyUseProxy = proxyUseProxy;
this.proxyBypassOnLocal = proxyBypassOnLocal;
}
protected override HttpMessageHandler CreateHandler(CreateHttpClientArgs args)
{
var proxy = new WebProxy(Address: proxyAddress, BypassOnLocal: proxyBypassOnLocal, BypassList: null, Credentials: null);
var webRequestHandler = new HttpClientHandler()
{
Proxy = proxy,
UseProxy = proxyUseProxy,
UseCookies = false
};
return webRequestHandler;
}
}
public class PushHandler : IRequestHandler<Request_PushFromBackend, Response_PushFromBackend>
{
private readonly IDBCommander _commander;
private readonly ILogger<PushHandler> _logger;
public PushFromBackendHandler(ILogger<PushHandler> logger, IDBCommander commander)
{
_logger = logger;
_commander = commander;
}
public async Task<Response_PushFromBackend> Handle(Request_PushFromBackend request, CancellationToken cancellationToken)
{
var sw = Stopwatch.StartNew();
bool isProxyUsing = false;
try
{
var resultFCMcreds = await _commander.Get_FCMcredentials(); // settings from DB
var resultProxy = await _commander.Get_ProxySettings(); // settings from DB
var defaultApp = FirebaseApp.DefaultInstance;
if (defaultApp == null)
{
var serviceAccountEmail = resultFCMcreds?.ServiceAccountEmail;
var PrivateKey = resultFCMcreds?.PrivateKey;
var credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
ProjectId = resultFCMcreds?.ProjectId,
HttpClientFactory = new ProxyHttpClientFactory2(resultProxy?.Address, (bool)resultProxy?.UseProxy, (bool)resultProxy?.BypassOnLocal),
}.FromPrivateKey(PrivateKey));
defaultApp = FirebaseApp.Create(new AppOptions()
{
Credential = GoogleCredential.FromServiceAccountCredential(credential),
HttpClientFactory = new ProxyHttpClientFactory2(resultProxy?.Address, (bool)resultProxy?.UseProxy, (bool)resultProxy?.BypassOnLocal)
});
}
FirebaseAdmin.Messaging.Aps aps_data = new Aps();
if (request.PushMode == 1)
{
aps_data.ContentAvailable = true;
}
var message = new Message()
{
//Topic = "news",
Token = request.FirebaseToken,
Apns = new ApnsConfig()
{
Aps = aps_data
},
Data = new Dictionary<string, string>()
{
["Changed"] = "true",
},
Notification = (request.PushMode == 1) ? null : new Notification
{
Title = $"System Notification {((request.PushMode == 1) ? " (SILENT)" : " (NORMAL)")}",
Body = $"Message: {request.PushMessage}"
}
};
var messaging = FirebaseMessaging.DefaultInstance;
var result = await messaging.SendAsync(message);
_logger.LogInformation($"result: {result}");
return new Response_PushFromBackend()
{
....
};
}
catch (Exception ex)
{
return new Response_PushFromBackend()
{
Error = ex.Message
};
}
}
}
}

Long tap and drop pin in xamarin forms maps

I used Xamarin.Forms.Maps nuget package and displayed map on the device. I am able to show the pin on external button tap with the help of following code, but unable to achieve same on map tap to drop a pin on a specific location.
public void addPin(double latitude, double longitude, string labelName)
{
Position position = new Position(latitude, longitude);
_assignedPin = new Pin
{
Type = PinType.Place,
Position = position,
Label = labelName,
Address = "custom detail info"
};
map.Pins.Add(_assignedPin);
}
I followed this blog to get lat long on map, but map does not display the pin on the map.
We need to add the code in renderer itself to drop pin using xamarin.forms.maps
In Android: Renderer class:
private void googleMap_MapClick(object sender, GoogleMap.MapClickEventArgs e)
{
Map.Pins.Add(new Pin
{
Label = "Pin from tap",
Position = new Position(e.Point.Latitude, e.Point.Longitude))
}
}
And in iOS Renderer class:
[assembly: ExportRenderer(typeof(ExtMap), typeof(ExtMapRenderer))]
namespace Xamarin.iOS.CustomRenderers
{
/// <summary>
/// Renderer for the xamarin ios map control
/// </summary>
public class ExtMapRenderer : MapRenderer
{
private readonly UITapGestureRecognizer _tapRecogniser;
public ExtMapRenderer()
{
_tapRecogniser = new UITapGestureRecognizer(OnTap)
{
NumberOfTapsRequired = 1,
NumberOfTouchesRequired = 1
};
}
protected override IMKAnnotation CreateAnnotation(Pin pin)
{
return base.CreateAnnotation(pin);
}
class BasicMapAnnotation : MKAnnotation
{
CLLocationCoordinate2D coord;
string title, subtitle;
public override CLLocationCoordinate2D Coordinate { get { return coord; } }
public override void SetCoordinate(CLLocationCoordinate2D value)
{
coord = value;
}
public override string Title { get { return title; } }
public override string Subtitle { get { return subtitle; } }
public BasicMapAnnotation(CLLocationCoordinate2D coordinate, string title, string subtitle)
{
this.coord = coordinate;
this.title = title;
this.subtitle = subtitle;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
}
private async void OnTap(UITapGestureRecognizer recognizer)
{
var cgPoint = recognizer.LocationInView(Control);
var nativeMap = Control as MKMapView;
var location = ((MKMapView)Control).ConvertPoint(cgPoint, Control);
((ExtMap)Element).OnTap(new Position(location.Latitude, location.Longitude));
try
{
var lat = location.Latitude;
var lon = location.Longitude;
var placemarks = await Geocoding.GetPlacemarksAsync(lat, lon);
var placemark = placemarks?.FirstOrDefault();
if (placemark != null)
{
var geocodeAddress =
$"AdminArea: {placemark.AdminArea}\n" +
$"CountryCode: {placemark.CountryCode}\n" +
$"CountryName: {placemark.CountryName}\n" +
$"FeatureName: {placemark.FeatureName}\n" +
$"Locality: {placemark.Locality}\n" +
$"PostalCode: {placemark.PostalCode}\n" +
$"SubAdminArea: {placemark.SubAdminArea}\n" +
$"SubLocality: {placemark.SubLocality}\n" +
$"SubThoroughfare: {placemark.SubThoroughfare}\n" +
$"Thoroughfare: {placemark.Thoroughfare}\n";
Console.WriteLine(geocodeAddress);
var annotation = new BasicMapAnnotation(new CLLocationCoordinate2D(lat, lon), placemark.Thoroughfare, placemark.SubThoroughfare);
nativeMap.AddAnnotation(annotation);
}
}
catch (FeatureNotSupportedException fnsEx)
{
// Feature not supported on device
Console.WriteLine(fnsEx);
}
catch (Exception ex)
{
// Handle exception that may have occurred in geocoding
Console.WriteLine(ex);
}
}
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
if (Control != null)
Control.RemoveGestureRecognizer(_tapRecogniser);
base.OnElementChanged(e);
if (Control != null)
Control.AddGestureRecognizer(_tapRecogniser);
}
}
}

Remote notification in xamarin.forms

I created finishlaunching() in AppDelegate.cs and RegisteredForRemoteNotifications() but when I try to get device token it does not call RegisteredForRemoteNotifications() and I created push notification using Urban airship and for Test, I need device token.
How can I get Device Token using RemoteNotification ?
AppDelegate.cs contains below code...
using System;
using System.Reflection;
using Test.Interfaces;
using Test.Interfaces.UAIntegration;
using Test.iOS.UAIntegration;
using TestWebAPI.Client;
using TestWebAPI.Models;
using TestWebAPI.Models.ResponseModels;
using CoreGraphics;
using Facebook.CoreKit;
using Foundation;
using GalaSoft.MvvmLight.Ioc;
using HockeyApp.iOS;
using UIKit;
using UrbanAirship;
using Xamarin.Forms.Platform.iOS;
using FacebookProfile = Facebook.CoreKit.Profile;
using FacebookSettings = Facebook.CoreKit.Settings;
using StoreKit;
using System.Diagnostics;
using Test.Services;
namespace Test.iOS
{
[Register("AppDelegate")]
public partial class AppDelegate : FormsApplicationDelegate
{
private NetworkManager _networkManager;
public override bool FinishedLaunching(UIApplication uiApplication, NSDictionary launchOptions)
{
UAirship.TakeOff();
RegisterServices();
//SetupHockeyAppSDK ();
SetupFacebookSDK();
FFImageLoading.Forms.Touch.CachedImageRenderer.Init();
var dummy = new FFImageLoading.Forms.Touch.CachedImageRenderer();
Xamarin.Forms.Forms.Init();
LoadApplication(new App());
UIApplication.SharedApplication.StatusBarHidden = false;
UIApplication.SharedApplication.SetStatusBarStyle(UIStatusBarStyle.LightContent, false);
_networkManager = new NetworkManager();
//HACK
OverrideDefaultListViewCustomActionsColors();
UAirship.Push().UserPushNotificationsEnabled = true;
//string chanelid = UAirship.Push().ChannelID;
//string token = UAirship.Push().DeviceToken;
new PhotoAccessChecker();
//return ApplicationDelegate.SharedInstance.FinishedLaunching(uiApplication, launchOptions);
return base.FinishedLaunching(uiApplication, launchOptions);
}
public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
{
return ApplicationDelegate.SharedInstance.OpenUrl(application, url, sourceApplication, annotation);
}
void SetupFacebookSDK()
{
FacebookProfile.EnableUpdatesOnAccessTokenChange(true);
FacebookSettings.AppID = "983921778349321";
FacebookSettings.DisplayName = "Test – Test";
}
//void SetupHockeyAppSDK ()
//{
// BITHockeyManager.SharedHockeyManager.Configure ("88bf22ad3da341eab128b28cf316148f");
// BITHockeyManager.SharedHockeyManager.StartManager ();
// BITHockeyManager.SharedHockeyManager.Authenticator.AuthenticateInstallation ();
// BITHockeyManager.SharedHockeyManager.UpdateManager.AlwaysShowUpdateReminder = false;
//}
void RegisterServices()
{
SimpleIoc.Default.Register<IStatisticsCollector, FirebaseStatisticsCollector>(true);
SimpleIoc.Default.Register<HttpMessageHandlerFactory>();
SimpleIoc.Default.Register<ISettingsOpener, SettingsOpener>();
SimpleIoc.Default.Register<IPhotoAccessChecker, PhotoAccessChecker>();
SimpleIoc.Default.Register<IImageToStreamConverter, ImageToStreamConverter>();
SimpleIoc.Default.Register<IAuthenticationApiClient, AuthenticationApiClient>();
SimpleIoc.Default.Register<IUtilityApiClient, UtilityApiClient>();
SimpleIoc.Default.Register<IProfileApiClient, ProfileApiClient>();
SimpleIoc.Default.Register<IPaymentApiClient, PaymentApiClient>();
SimpleIoc.Default.Register<IInboxApiClient, InboxApiClient>();
SimpleIoc.Default.Register<IBlogApiClient, BlogApiClient>();
SimpleIoc.Default.Register<IUserSettings, UserSettings>();
SimpleIoc.Default.Register<IPreferences, Preferences>();
SimpleIoc.Default.Register<IEncryptor, Encryptor>();
SimpleIoc.Default.Register<ITimerFactory, TimerFactory>();
SimpleIoc.Default.Register<ISuggestionService<Location>, LocationService>();
SimpleIoc.Default.Register<ISuggestionService<Gender>, GenderService>();
SimpleIoc.Default.Register<ISuggestionService<Religion>, ReligionService>();
SimpleIoc.Default.Register<ISuggestionService<Diet>, DietService>();
SimpleIoc.Default.Register<ISuggestionService<Drink>, DrinkService>();
SimpleIoc.Default.Register<ISuggestionService<Smoke>, SmokeService>();
SimpleIoc.Default.Register<ISuggestionService<Occupation>, OccupationService>();
SimpleIoc.Default.Register<ISuggestionService<Education>, EducationService>();
SimpleIoc.Default.Register<ISuggestionService<MaritalStatus>, MaritalService>();
SimpleIoc.Default.Register<ISuggestionService<MemberTag>, TagsService>();
SimpleIoc.Default.Register<ISuggestionService<HeightFeet>, HeightFeetService>();
SimpleIoc.Default.Register<ISuggestionService<HeightInches>, HeightInchesService>();
SimpleIoc.Default.Register<ISuggestionService<BlockReason>, BlockReasonService>();
SimpleIoc.Default.Register<ISuggestionService<CancellationReason>, CancellationReasonService>();
SimpleIoc.Default.Register<ISuggestionService<HideProfileReason>, HideProfileReasonService>();
SimpleIoc.Default.Register<IDialogService, DialogService>();
SimpleIoc.Default.Register<ICropImageService, CropImageService>();
SimpleIoc.Default.Register<IFileService, FileService>();
SimpleIoc.Default.Register<INotificationService, NotificationService>();
SimpleIoc.Default.Register<IFacebookService, FacebookService>();
SimpleIoc.Default.Register<IUrbanAirshipService, UrbanAirshipService>();
SimpleIoc.Default.Register<IInAppService, InAppService>();
SimpleIoc.Default.Register<SuggestionServices>();
}
void OverrideDefaultListViewCustomActionsColors()
{
CGRect rect = new CGRect(0, 0, 1, 1);
CGSize size = rect.Size;
UIGraphics.BeginImageContext(size);
CGContext currentContext = UIGraphics.GetCurrentContext();
currentContext.SetFillColor(Colors.d8Red.ToCGColor());
currentContext.FillRect(rect);
var backgroundImage = UIGraphics.GetImageFromCurrentImageContext();
currentContext.Dispose();
var contextActionsCellType = Type.GetType("Xamarin.Forms.Platform.iOS.ContextActionsCell, Xamarin.Forms.Platform.iOS, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null");
// Now change the static field value!
var backgroundImageField = contextActionsCellType.GetField("DestructiveBackground", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
backgroundImageField.SetValue(null, backgroundImage);
rect = new CGRect(0, 0, 1, 1);
size = rect.Size;
UIGraphics.BeginImageContext(size);
currentContext = UIGraphics.GetCurrentContext();
currentContext.SetFillColor(Colors.d8Purple.ToCGColor());
currentContext.FillRect(rect);
backgroundImage = UIGraphics.GetImageFromCurrentImageContext();
currentContext.Dispose();
backgroundImageField = contextActionsCellType.GetField("NormalBackground", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
backgroundImageField.SetValue(null, backgroundImage);
}
public override void WillTerminate(UIApplication application)
{
(App.Locator.InApp.TheInAppService as InAppService).WillTerminate();
base.WillTerminate(application);
}
}
}

Generating a Barcode in c#.net

I am working on a project where i want to generate Bar-code based on an user-ID. I need a code which can generate bar-code and also is encrypted. I have found a few codes but they do not seem very helpful. Thank you in advance for help. i have tried this code but it does not provide me the barcode image.
`private void Page_Load(object sender, System.EventArgs e)
{
// Get the Requested code to be created.
string Code = Request["code"].ToString();
// Multiply the lenght of the code by 40 (just to have enough width)
int w = Code.Length * 40;
// Create a bitmap object of the width that we calculated and height of 100
Bitmap oBitmap = new Bitmap(w,100);
// then create a Graphic object for the bitmap we just created.
Graphics oGraphics = Graphics.FromImage(oBitmap);
// Now create a Font object for the Barcode Font
// (in this case the IDAutomationHC39M) of 18 point size
Font oFont = new Font("IDAutomationHC39M", 18);
// Let's create the Point and Brushes for the barcode
PointF oPoint = new PointF(2f, 2f);
SolidBrush oBrushWrite = new SolidBrush(Color.Black);
SolidBrush oBrush = new SolidBrush(Color.White);
// Now lets create the actual barcode image
// with a rectangle filled with white color
oGraphics.FillRectangle(oBrush, 0, 0, w, 100);
// We have to put prefix and sufix of an asterisk (*),
// in order to be a valid barcode
oGraphics.DrawString("*" + Code + "*", oFont, oBrushWrite, oPoint);
// Then we send the Graphics with the actual barcode
Response.ContentType = "image/jpeg" ;
oBitmap.Save (Response.OutputStream, ImageFormat.Jpeg);
}`
Check out this link it is a simple code 39 barcode display which supports a header and footer, printing, saving, and is pretty well customizable. For the encryption part you will have to encrypt your message before converting it to a barcode.
From the link.
Using the code The code is very simple to use, just plop the control
onto a form and you are ready to start customizing it via the
Properties window or through your code. In addition to the
properties, there are also two public functions of interest: public
void Print() This function will display a print dialog and then print
the contents of the control to the selected printer. public void
SaveImage(string filename) This function will save the contents of the
control to a bitmap image specified by filename.
http://www.codeproject.com/Articles/10344/Barcode-NET-Control
Please try Following Code you have to add "FREE3OF9.TTF" font file in your code
Default.aspx.cs code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
////GenerateBarCode.GenerateBarCodes("dfdfdf", Label1);
GenerateBarCode();
}
}
private void GenerateBarCode()
{
WSBarcodeGenerator.BarCodeGenerator barCodeGen = new WSBarcodeGenerator.BarCodeGenerator();
int barSize = 30;
System.Byte[] imgBarcode =Code39("123456", barSize, true, "Centralbiz...");
MemoryStream memStream = new MemoryStream(imgBarcode);
Bitmap bitmap = new Bitmap(memStream);
bitmap.Save(memStream, ImageFormat.Png);
var base64Data = Convert.ToBase64String(memStream.ToArray());
imgBar.Attributes.Add("src", "data:image/png;base64," + base64Data);
//Response.Write(bitmap);
//var base64Data = Convert.ToBase64String(memStream.ToArray());
//imgBar.Attributes.Add("src", "png");
}
public byte[] Code39(string code, int barSize, bool showCodeString, string title)
{
Code39 c39 = new Code39();
// Create stream....
MemoryStream ms = new MemoryStream();
c39.FontFamilyName = "Free 3 of 9";
c39.FontFileName = Server.MapPath("FREE3OF9.TTF");
c39.FontSize = barSize;
c39.ShowCodeString = showCodeString;
if (title + "" != "")
c39.Title = title;
Bitmap objBitmap = c39.GenerateBarcode(code);
objBitmap.Save(ms, ImageFormat.Png);
//return bytes....
return ms.GetBuffer();
}
}
public class Code39
{
private const int _itemSepHeight = 3;
SizeF _titleSize = SizeF.Empty;
SizeF _barCodeSize = SizeF.Empty;
SizeF _codeStringSize = SizeF.Empty;
#region Barcode Title
private string _titleString = null;
private Font _titleFont = null;
public string Title
{
get { return _titleString; }
set { _titleString = value; }
}
public Font TitleFont
{
get { return _titleFont; }
set { _titleFont = value; }
}
#endregion
#region Barcode code string
private bool _showCodeString = false;
private Font _codeStringFont = null;
public bool ShowCodeString
{
get { return _showCodeString; }
set { _showCodeString = value; }
}
public Font CodeStringFont
{
get { return _codeStringFont; }
set { _codeStringFont = value; }
}
#endregion
#region Barcode Font
private Font _c39Font = null;
private float _c39FontSize = 12;
private string _c39FontFileName = null;
private string _c39FontFamilyName = null;
public string FontFileName
{
get { return _c39FontFileName; }
set { _c39FontFileName = value; }
}
public string FontFamilyName
{
get { return _c39FontFamilyName; }
set { _c39FontFamilyName = value; }
}
public float FontSize
{
get { return _c39FontSize; }
set { _c39FontSize = value; }
}
private Font Code39Font
{
get
{
if (_c39Font == null)
{
PrivateFontCollection pfc = new PrivateFontCollection();
pfc.AddFontFile(_c39FontFileName);
FontFamily family = new FontFamily(_c39FontFamilyName, pfc);
_c39Font = new Font(family, _c39FontSize);
}
return _c39Font;
}
}
#endregion
public Code39()
{
_titleFont = new Font("Arial", 10);
_codeStringFont = new Font("Arial", 10);
}
#region Barcode Generation
public Bitmap GenerateBarcode(string barCode)
{
int bcodeWidth = 0;
int bcodeHeight = 0;
// Get the image container...
Bitmap bcodeBitmap = CreateImageContainer(barCode, ref bcodeWidth, ref bcodeHeight);
Graphics objGraphics = Graphics.FromImage(bcodeBitmap);
// Fill the background
objGraphics.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, bcodeWidth, bcodeHeight));
int vpos = 0;
// Draw the title string
if (_titleString != null)
{
objGraphics.DrawString(_titleString, _titleFont, new SolidBrush(Color.Black), XCentered((int)_titleSize.Width, bcodeWidth), vpos);
vpos += (((int)_titleSize.Height) + _itemSepHeight);
}
// Draw the barcode
objGraphics.DrawString(barCode, Code39Font, new SolidBrush(Color.Black), XCentered((int)_barCodeSize.Width, bcodeWidth), vpos);
// Draw the barcode string
if (_showCodeString)
{
vpos += (((int)_barCodeSize.Height));
objGraphics.DrawString(barCode, _codeStringFont, new SolidBrush(Color.Black), XCentered((int)_codeStringSize.Width, bcodeWidth), vpos);
}
// return the image...
return bcodeBitmap;
}
private Bitmap CreateImageContainer(string barCode, ref int bcodeWidth, ref int bcodeHeight)
{
Graphics objGraphics;
// Create a temporary bitmap...
Bitmap tmpBitmap = new Bitmap(1, 1, PixelFormat.Format32bppArgb);
objGraphics = Graphics.FromImage(tmpBitmap);
// calculate size of the barcode items...
if (_titleString != null)
{
_titleSize = objGraphics.MeasureString(_titleString, _titleFont);
bcodeWidth = (int)_titleSize.Width;
bcodeHeight = (int)_titleSize.Height + _itemSepHeight;
}
_barCodeSize = objGraphics.MeasureString(barCode, Code39Font);
bcodeWidth = Max(bcodeWidth, (int)_barCodeSize.Width);
bcodeHeight += (int)_barCodeSize.Height;
if (_showCodeString)
{
_codeStringSize = objGraphics.MeasureString(barCode, _codeStringFont);
bcodeWidth = Max(bcodeWidth, (int)_codeStringSize.Width);
bcodeHeight += (_itemSepHeight + (int)_codeStringSize.Height);
}
// dispose temporary objects...
objGraphics.Dispose();
tmpBitmap.Dispose();
return (new Bitmap(bcodeWidth, bcodeHeight, PixelFormat.Format32bppArgb));
}
#endregion
#region Auxiliary Methods
private int Max(int v1, int v2)
{
return (v1 > v2 ? v1 : v2);
}
private int XCentered(int localWidth, int globalWidth)
{
return ((globalWidth - localWidth) / 2);
}
#endregion
}
Default.aspx code
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>
Welcome to ASP.NET!
</h2>
<p>
To learn more about ASP.NET visit www.asp.net.
</p>
<p>
You can also find <a href="http://go.microsoft.com/fwlink/?LinkID=152368&clcid=0x409"
title="MSDN ASP.NET Docs">documentation on ASP.NET at MSDN</a>.
</p>
<asp:Image ID="imgBar" runat="server" />
</asp:Content>

Selenium webdriver C# - Taking full page screenshot

Can anyone help me to take a full page screenshot using Selenium webdriver. I am using c#/Nunit. The current method i am using is not taking the full browser page.
I am using the code below to take the screenshot.
public void TakeScreenShot(IWebDriver webDriver,string testName,string className)
{
string folderName = String.Format("{0}.{1}", className, testName);
// Create Screenshot folder
string createdFolderLocation = CreateFolder(folderName);
// Take the screenshot
Screenshot ss = ((ITakesScreenshot)webDriver).GetScreenshot();
string screenshot = ss.AsBase64EncodedString;
byte[] screenshotAsByteArray = ss.AsByteArray;
// Save the screenshot
ss.SaveAsFile((string.Format("{0}\\{1}",createdFolderLocation,testName + ".Jpeg")), System.Drawing.Imaging.ImageFormat.Jpeg);
ss.ToString();
}
You can use this package https://www.nuget.org/packages/Noksa.WebDriver.ScreenshotsExtensions/
In order to take a screenshot of the entire page, use the VerticalCombineDecorator:
var vcs = new VerticalCombineDecorator(new ScreenshotMaker());
var screen = _driver.TakeScreenshot(vcs);
"Full-page" screenshots are defined by WebDriver to include the entirety of the page displayed in the browser, not the browser chrome (URL bar, toolbar, window resizing handles, and so on). If you don't care about getting the full DOM in your screenshot, you don't need to use WebDriver to get your screenshot. You can use the API of your operating system to handle that instead.
This one I used in our solution:
public byte[] TakeScreenshot()
{
try
{
var getMaxSide = "return Math.max(document.body.scroll{0}, document.body.offset{0}, document.documentElement.client{0}, document.documentElement.scroll{0}, document.documentElement.offset{0})";
var scrollHeight = (Driver as IJavaScriptExecutor).ExecuteScript(string.Format(getMaxSide, "Height"));
var scrollWidth = (Driver as IJavaScriptExecutor).ExecuteScript(string.Format(getMaxSide, "Width"));
Driver.Manage().Window.Size = new Size(int.Parse(scrollWidth.ToString()), int.Parse(scrollHeight.ToString()));
return (Driver as ITakesScreenshot).GetScreenshot().AsByteArray;
}
catch
{
return Array.Empty<byte>();
}
}
Then you can use the result to attach it to e.g. Allure or NUnit test results:
private void AttachScreenshot()
{
var screenshot = _browser?.TakeScreenshot();
if (screenshot.Length > 0)
{
// add screenshot to test results
var path = DateTime.Now.Ticks.ToString() + ".png";
File.WriteAllBytes(path, screenshot);
TestContext.AddTestAttachment(path, "screenshot");
// attach screenshot to Allure report
AllureLifecycle.Instance.AddAttachment("screenshot", "image/png", screenshot);
}
}
Try changing the size of the browser window to something huge before taking your screen shot. I have the size to 10 less than the width, and 10 less than the height. Try adding rather than subtracting.
driver = new FirefoxDriver(firefoxProfile);
if (Config.MAXIMIZE_BROWSER_WINDOW)
{
driver.Manage().Window.Size = new System.Drawing.Size(System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width - 10, System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height - 10);
}
you may try this
IWebDriver driver = new PhantomJSDriver();
driver.Navigate().GoToUrl("http://www.google.com");
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile("image.png", ImageFormat.Png);
Greetings from 2017))!
If the page size is larger than the screen size - you can use the PhantomJS driver (PhantomJS download page)
var fileName = "test.png";
var size = new Size(800, 2000);
var url = "https://stackoverflow.com/";
using (var driver = new PhantomJSDriver())
{
driver.Manage().Window.Size = size;
driver.Navigate().GoToUrl(url);
((ITakesScreenshot)driver)
.GetScreenshot()
.SaveAsFile(fileName, ImageFormat.Png);
driver.Close();
}
I remeber that ((ITakesScreenshot)webDriver).GetScreenshot(); takes full page screenshot but if you have some ajax request and other loading elements you can add scrolling and at the end to wait some seconds, after that you will know that it took full loaded page screenshot.
for (int second = 0;; second++)
{
if (second >= 4)
{
break;
}
((IJavaScriptExecutor)Global.Driver).ExecuteScript("window.scrollBy(0,800)", string.Empty);
Thread.Sleep(500);
}
Thread.Sleep(3000);
Try this hope it will work fine for u.
public void TakeScreenshot(string SSName)
{
try
{
string path = "D:\\WorkSpace\\Screenshot\\";
Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot();
ss.SaveAsFile((path + SSName), System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
}
Changing browser height doesn't always work. This is the solution I used. It scrolls through the page and composes the full-page screenshot.
public static Image TakeFullPageScreenshot(this RemoteWebDriver driver, int maxHeight = 10000)
{
Bitmap fullPageScreenshot = null;
using (var fullMs = new MemoryStream((driver.GetScreenshot()).AsByteArray)) {
fullPageScreenshot = Image.FromStream(fullMs) as Bitmap;
}
var originalPageOffset = driver.GetPageOffset();
var prevPageOffset = 0;
var currentPageOffset = 0;
var scrollLength = (int)(driver.Manage().Window.Size.Height / 1.5);
while (fullPageScreenshot.Height < maxHeight)
{
prevPageOffset = driver.GetPageOffset().Y;
driver.ScrollPageBy(0, scrollLength);
System.Threading.Thread.Sleep(500);
currentPageOffset = driver.GetPageOffset().Y;
if (prevPageOffset == currentPageOffset)
{
break;
}
var pageMovedBy = currentPageOffset - prevPageOffset;
using (var ms = new MemoryStream(driver.GetScreenshot().AsByteArray))
{
using (var viewPortScreenshot = Image.FromStream(ms) as Bitmap)
{
var croppedScreenshot = CropBitmapAtRect(viewPortScreenshot, new Rectangle(0, viewPortScreenshot.Height - pageMovedBy, viewPortScreenshot.Width, pageMovedBy));
var newFullPage = AppendBitmap(fullPageScreenshot, croppedScreenshot);
fullPageScreenshot.Dispose();
fullPageScreenshot = newFullPage;
}
}
}
driver.ScrollPageTo(originalPageOffset.X, originalPageOffset.Y);
return fullPageScreenshot;
}
public static Bitmap CropBitmapAtRect(Bitmap b, Rectangle r)
{
Bitmap nb = new Bitmap(r.Width, r.Height);
using (Graphics g = Graphics.FromImage(nb))
{
g.DrawImage(b, -r.X, -r.Y);
return nb;
}
}
public static Bitmap AppendBitmap(Bitmap source, Bitmap target, int spacing = 0)
{
int w = Math.Max(source.Width, target.Width);
int h = source.Height + target.Height + spacing;
Bitmap bmp = new Bitmap(w, h);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawImage(source, 0, 0);
g.DrawImage(target, 0, source.Height + spacing);
}
return bmp;
}
public static void ScrollPageBy(this RemoteWebDriver driver, int x = 0, int y = 0)
{
driver.ExecuteScript(#"window.scroll(window.pageXOffset + arguments[0], window.pageYOffset + arguments[1]);", x, y);
}
public static void ScrollPageTo(this RemoteWebDriver driver, int x = 0, int y = 0)
{
driver.ExecuteScript(#"window.scroll(arguments[0], arguments[1]);", x, y);
}
public static Point GetPageOffset(this RemoteWebDriver driver)
{
var offsetArray = driver.ExecuteScript(#"return [window.pageXOffset, window.pageYOffset];") as ReadOnlyCollection<object>;
var x = (long)offsetArray[0];
var y = (long)offsetArray[1];
return new Point((int)x, (int)y);
}
based on the answer from #Michal Kalous I created an etension class.
This also takes into account the font size currently set in widows and the real viewport size and removes the vertical scrollbar by setting body.style.overflowY to hidden.
Usage
RemoteWebDriver driver = new EdgeDriver();
driver.SetViewportSize(1200, 1200);
driver.Navigate().GoToUrl("https://www.bikereview.info/en/ktm-1290-super-duke-rr-innerhalb-von-48-minuten-ausverkauft.html");
Image tempImage = driver.TakeFullPageScreenshot();
tempImage.Save(#"c:\full.png", ImageFormat.Png);
driver.Close();
driver.Quit();
Extension-Class
using System;
using System.Drawing;
using System.IO;
using OpenQA.Selenium.Remote;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using OpenQA.Selenium;
namespace TestRenderHtmlToPng
{
public static class RemoteWebDriverExtensions
{
public static Image TakeFullPageScreenshot(this RemoteWebDriver driver, int maxHeight = 10000)
{
//Screenshots depend on fontscaleing-property in windows
double DpiScalingFactor = GetDpiScalingFactor();
Bitmap fullPageScreenshot = null;
using (var fullMs = new MemoryStream((driver.GetScreenshotOverflowHidden()).AsByteArray))
{
fullPageScreenshot = Image.FromStream(fullMs) as Bitmap;
}
var originalPageOffset = driver.GetPageOffset();
var prevPageOffset = 0;
var currentPageOffset = 0;
var scrollLength = driver.GetWindowInnerHeight();
while (fullPageScreenshot.Height < maxHeight)
{
prevPageOffset = driver.GetPageOffset().Y;
driver.ScrollPageBy(0, scrollLength);
System.Threading.Thread.Sleep(100);
currentPageOffset = driver.GetPageOffset().Y;
if (prevPageOffset == currentPageOffset)
{
break;
}
var pageMovedBy = currentPageOffset - prevPageOffset;
pageMovedBy = (int)(pageMovedBy * DpiScalingFactor);
using (var ms = new MemoryStream(driver.GetScreenshotOverflowHidden().AsByteArray))
{
Bitmap fullPageScreenshot1 = Image.FromStream(ms) as Bitmap;
using (var viewPortScreenshot = Image.FromStream(ms) as Bitmap)
{
var s = driver.Manage().Window.Size;
var croppedScreenshot = CropBitmapAtRect(viewPortScreenshot, new Rectangle(0, viewPortScreenshot.Height - pageMovedBy, viewPortScreenshot.Width, pageMovedBy));
var newFullPage = AppendBitmap(fullPageScreenshot, croppedScreenshot);
fullPageScreenshot.Dispose();
fullPageScreenshot = newFullPage;
}
}
}
driver.ScrollPageTo(originalPageOffset.X, originalPageOffset.Y);
return fullPageScreenshot;
}
private static Bitmap CropBitmapAtRect(Bitmap b, Rectangle r)
{
Bitmap nb = new Bitmap(r.Width, r.Height);
using (Graphics g = Graphics.FromImage(nb))
{
g.DrawImage(b, -r.X, -r.Y);
return nb;
}
}
private static Bitmap AppendBitmap(Bitmap source, Bitmap target, int spacing = 0)
{
int w = Math.Max(source.Width, target.Width);
int h = source.Height + target.Height + spacing;
Bitmap bmp = new Bitmap(w, h);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawImage(source, 0, 0);
g.DrawImage(target, 0, source.Height + spacing);
}
return bmp;
}
private static Screenshot GetScreenshotOverflowHidden(this RemoteWebDriver driver)
{
driver.ExecuteScript(#" document.body.style.overflowY = ""hidden"";");
var s = driver.GetScreenshot();
driver.ExecuteScript(#" document.body.style.overflowY = """";");
return s;
}
private static void ScrollPageBy(this RemoteWebDriver driver, int x = 0, int y = 0)
{
driver.ExecuteScript(#"window.scroll(window.pageXOffset + arguments[0], window.pageYOffset + arguments[1]);", x, y);
}
private static void ScrollPageTo(this RemoteWebDriver driver, int x = 0, int y = 0)
{
driver.ExecuteScript(#"window.scroll(arguments[0], arguments[1]);", x, y);
}
public static void SetViewportSize(this RemoteWebDriver driver, int width, int height)
{
var jsGetPadding = #"return [ window.outerWidth - window.innerWidth,window.outerHeight - window.innerHeight ];";
var paddingArray = driver.ExecuteScript(jsGetPadding) as ReadOnlyCollection<object>;
driver.Manage().Window.Size = new Size(width + int.Parse(paddingArray[0].ToString()), height + int.Parse(paddingArray[1].ToString()));
}
private static Point GetPageOffset(this RemoteWebDriver driver)
{
var offsetArray = driver.ExecuteScript(#"return [window.pageXOffset, window.pageYOffset];") as ReadOnlyCollection<object>;
var x = int.Parse(offsetArray[0].ToString());
var y = int.Parse(offsetArray[1].ToString().Split(',')[0]);
return new Point((int)x, (int)y);
}
private static int GetWindowInnerHeight(this RemoteWebDriver driver)
{
var Value = driver.ExecuteScript(#"return [window.innerHeight];") as ReadOnlyCollection<object>;
return int.Parse(Value[0].ToString());
}
[DllImport("gdi32.dll")]
private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
public enum DeviceCap
{
VERTRES = 10,
DESKTOPVERTRES = 117,
// http://pinvoke.net/default.aspx/gdi32/GetDeviceCaps.html
// https://stackoverflow.com/questions/5977445/how-to-get-windows-display-settings#answer-21450169
}
private static float GetDpiScalingFactor()
{
Graphics g = Graphics.FromHwnd(IntPtr.Zero);
IntPtr desktop = g.GetHdc();
int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);
float ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight;
return ScreenScalingFactor; // 1.25 = 125%
}
}
}

Resources