using System;
|
using AVFoundation;
|
using CoreGraphics;
|
using Foundation;
|
using UIKit;
|
|
namespace Shared
|
{
|
/// <summary>
|
/// 拍照或者选择图片
|
/// </summary>
|
public static class Camera
|
{
|
static readonly UIImagePickerController _picker;
|
static bool IsZoom;
|
|
/// <summary>
|
/// 拍照或者读取图片完成时调用的动作,string==null表示用户取消了拍照或者取消选择图片,string!=null,表示图片的路径
|
/// </summary>
|
static Action<string> _callback;
|
|
static Camera()
|
{
|
_picker = new UIImagePickerController();
|
_picker.Delegate = new MyCameraDelegate();
|
}
|
|
static string _fileName;
|
|
/// <summary>
|
/// Camera delegate.
|
/// </summary>
|
class MyCameraDelegate : UIImagePickerControllerDelegate
|
{
|
//16*9
|
public override void FinishedPickingMedia(UIImagePickerController picker, NSDictionary info)
|
{
|
picker.DismissModalViewController(true);
|
|
var tempPhoto = info.ValueForKey(new NSString("UIImagePickerControllerOriginalImage")) as UIImage;
|
|
tempPhoto = rotateImage(tempPhoto);
|
var width = tempPhoto.CGImage.Width;
|
var height = tempPhoto.CGImage.Height;
|
//System.Console.WriteLine("原宽度=" + width + "高度=" + height);
|
|
nfloat noScale = width / height;
|
nfloat scale = 16.0f / 9.0f;
|
if (!IsZoom)
|
{
|
scale = noScale;
|
}
|
nfloat x = 0, y = 0, w = width, h = height;
|
if (scale < noScale)
|
{
|
w = height * scale;
|
x = (width - w) / 2;
|
}
|
else
|
{
|
h = width / scale;
|
y = (height - h) / 2;
|
}
|
|
|
|
var imageRef = tempPhoto.CGImage.WithImageInRect(new CGRect(x, y, w, h));
|
UIImage newImage = UIImage.FromImage(imageRef);
|
|
|
// 关闭上下文
|
//System.Console.WriteLine("改变后的宽度=" + newImage.Size.Width + "高度=" + newImage.Size.Height);
|
string tempFilePath = System.IO.Path.Combine(Application.RootPath, _fileName);
|
NSError err = null;
|
float f = 0.1f;
|
NSData nsData = newImage.AsJPEG(f);
|
while (f < 1.0f)
|
{
|
if (200 * 1024 < nsData.Length)
|
{
|
break;
|
}
|
f += 0.1f;
|
nsData = newImage.AsJPEG(f);
|
}
|
if (nsData.Save(tempFilePath, false, out err))
|
{
|
//保存成功
|
}
|
else
|
{
|
Console.WriteLine("保存图片失");
|
}
|
newImage.Dispose();
|
_callback?.Invoke(tempFilePath);
|
_callback = null;
|
}
|
|
public override void Canceled(UIImagePickerController picker)
|
{
|
picker.DismissModalViewController(true);
|
_callback?.Invoke(null);
|
_callback = null;
|
}
|
|
UIImage rotateImage(UIImage aImage)
|
{
|
var imgRef = aImage.CGImage;
|
var width = imgRef.Width;
|
var height = imgRef.Height;
|
CGAffineTransform transform = CGAffineTransform.MakeIdentity();
|
CGRect bounds = new CGRect(0, 0, width, height);
|
nfloat scaleRatio = 1;
|
nfloat boundHeight;
|
UIImageOrientation orient = aImage.Orientation;
|
nfloat M_PI = 3.14159265358979323846f;
|
|
switch (orient)
|
{
|
case UIImageOrientation.Up: //EXIF = 1
|
transform = CGAffineTransform.MakeIdentity();
|
break;
|
case UIImageOrientation.UpMirrored: //EXIF = 2
|
transform = CGAffineTransform.MakeTranslation(width, 0.0f);
|
transform = CGAffineTransform.Scale(transform, -1.0f, 1.0f);
|
break;
|
case UIImageOrientation.Down: //EXIF = 3
|
transform = CGAffineTransform.MakeTranslation(width, height);
|
transform = CGAffineTransform.Rotate(transform, M_PI);
|
break;
|
case UIImageOrientation.DownMirrored: //EXIF = 4
|
transform = CGAffineTransform.MakeTranslation(0.0f, height);
|
transform = CGAffineTransform.Scale(transform, 1.0f, -1.0f);
|
break;
|
case UIImageOrientation.LeftMirrored: //EXIF = 5
|
boundHeight = bounds.Height;
|
bounds.Height = bounds.Size.Width;
|
bounds.Width = boundHeight;
|
transform = CGAffineTransform.MakeTranslation(height, width);
|
transform = CGAffineTransform.Scale(transform, -1.0f, 1.0f);
|
transform = CGAffineTransform.Rotate(transform, 3.0f * M_PI / 2.0f);
|
break;
|
case UIImageOrientation.Left: //EXIF = 6
|
boundHeight = bounds.Height;
|
bounds.Height = bounds.Width;
|
bounds.Width = boundHeight;
|
transform = CGAffineTransform.MakeTranslation(0.0f, width);
|
transform = CGAffineTransform.Rotate(transform, 3.0f * M_PI / 2.0f);
|
break;
|
case UIImageOrientation.RightMirrored: //EXIF = 7
|
boundHeight = bounds.Height;
|
bounds.Height = bounds.Width;
|
bounds.Width = boundHeight;
|
transform = CGAffineTransform.MakeScale(-1.0f, 1.0f);
|
transform = CGAffineTransform.Rotate(transform, M_PI / 2.0f);
|
break;
|
case UIImageOrientation.Right: //EXIF = 8
|
boundHeight = bounds.Height;
|
bounds.Height = bounds.Width;
|
bounds.Width = boundHeight;
|
transform = CGAffineTransform.MakeTranslation(height, 0.0f);
|
transform = CGAffineTransform.Rotate(transform, M_PI / 2.0f);
|
break;
|
//default:
|
// [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
|
}
|
|
UIGraphics.BeginImageContext(bounds.Size);
|
var context = UIGraphics.GetCurrentContext();
|
if (orient == UIImageOrientation.Right || orient == UIImageOrientation.Left)
|
{
|
context.ScaleCTM(-scaleRatio, scaleRatio);
|
context.TranslateCTM(-height, 0);
|
}
|
else
|
{
|
context.ScaleCTM(scaleRatio, -scaleRatio);
|
context.TranslateCTM(0, -height);
|
}
|
|
context.ConcatCTM(transform);
|
UIGraphics.GetCurrentContext().DrawImage(new CGRect(0, 0, width, height), imgRef);
|
UIImage imageCopy = UIGraphics.GetImageFromCurrentImageContext();
|
imgRef.Dispose();
|
UIGraphics.EndImageContext();
|
return imageCopy;
|
}
|
}
|
|
/// <summary>
|
/// 拍照
|
/// </summary>
|
/// <param name="callback">回调函数</param>
|
/// <param name="fileName">文件名</param>
|
public static void TakePicture(Action<string> callback, string fileName, bool isZoom = true)
|
{
|
_fileName = fileName;
|
_callback = callback;
|
_picker.SourceType = UIImagePickerControllerSourceType.Camera;
|
IsZoom = isZoom;
|
if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad)
|
{
|
if (!UIImagePickerController.IsCameraDeviceAvailable(UIImagePickerControllerCameraDevice.Front))
|
{
|
return;
|
}
|
_picker.ModalTransitionStyle = UIModalTransitionStyle.CrossDissolve;
|
currentVC.PresentModalViewController(_picker, true);
|
}
|
else
|
{
|
currentVC.PresentModalViewController(_picker, true);
|
}
|
}
|
|
/// <summary>
|
/// 选择图片
|
/// </summary>
|
/// <param name="callback">回调函数</param>
|
/// <param name="fileName">文件名</param>
|
public static void SelectPicture(Action<string> callback, string fileName, bool isZoom = true)
|
{
|
_fileName = fileName;
|
_callback = callback;
|
_picker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
|
IsZoom = isZoom;
|
if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad)
|
{
|
NSOperationQueue.MainQueue.AddOperation(() =>
|
{
|
_picker.ModalTransitionStyle = UIModalTransitionStyle.CoverVertical;
|
var popover = new UIPopoverController(_picker) { PopoverContentSize = Application.RootFrameLayout.Frame.Size };
|
popover.PresentFromRect(new CGRect(95, 235, 300, 300), Application.RootFrameLayout, UIPopoverArrowDirection.Down | UIPopoverArrowDirection.Left, true);
|
});
|
}
|
else
|
{
|
currentVC.PresentModalViewController(_picker, true);
|
}
|
}
|
|
//获取当前屏幕显示的viewcontroller
|
static UIViewController currentVC
|
{
|
get
|
{
|
var rootViewController = UIApplication.SharedApplication.KeyWindow.RootViewController;
|
var currentVC = getCurrentVCFrom(rootViewController);
|
return currentVC;
|
}
|
}
|
|
static UIViewController getCurrentVCFrom(UIViewController rootVC)
|
{
|
UIViewController currentVC;
|
if (rootVC.PresentedViewController != null)
|
{
|
// 视图是被presented出来的
|
rootVC = rootVC.PresentedViewController;
|
}
|
if (rootVC.GetType() == typeof(UITabBarController))
|
{
|
// 根视图为UITabBarController
|
currentVC = getCurrentVCFrom((rootVC as UITabBarController).SelectedViewController);
|
}
|
else if (rootVC.GetType() == typeof(UINavigationController))
|
{
|
// 根视图为UINavigationController
|
currentVC = getCurrentVCFrom((rootVC as UINavigationController).VisibleViewController);
|
}
|
else
|
{
|
// 根视图为非导航类
|
currentVC = rootVC;
|
}
|
return currentVC;
|
}
|
}
|
}
|