Unity3D,獲取相簿圖片,手機拍照
阿新 • • 發佈:2019-02-08
Unity端
- 先新建個專案吧,新增一個
Button
和兩個UIimage
吧。之後我們提取的相片會在UIimage上顯示。
至於為什麼要兩個,主要是一會我還要進行圖片的壓縮。然後把小圖也顯示出來。
- 新建個指令碼,程式碼如下:
public void GetBigImage(string filename){
string path="file://"+platformPath+filename;
Debug.Log (path);
StartCoroutine (loadImage(path,true));
}
public void GetSmallImage(string filename){
string path="file://"+platformPath+filename;
Debug.Log (path);
StartCoroutine (loadImage(path,false));
}
public void OnClickButton(){
if(Application.platform != RuntimePlatform.OSXEditor){
_GetImage();
}
}
public string platformPath{
get{
string path=null;
if(Application.platform==RuntimePlatform.IPhonePlayer)//判斷平臺
{
path= Application.persistentDataPath.Substring (0, Application.persistentDataPath.Length - 5);//ios 平臺 就會獲取documents路徑
path = path.Substring(0 , path.LastIndexOf('/'))+"/Documents/";
}
else
{
path=Application.dataPath+"/GameData/";//pc平臺 獲取當前工程GameData/的路徑 GameData需要自己新建
}
return path;
}
}
IEnumerator loadImage(string path,bool isBig){
WWW www = new WWW(path);
yield return www;
if (www.isDone && www.error == null) {
if(isBig){
Big_Spr = Sprite.Create (www.texture, new Rect (0, 0, www.texture.width, www.texture.height), new Vector2 (0, 0));
image.sprite = Big_Spr;
}else{
Small_Spr = Sprite.Create (www.texture, new Rect (0, 0, www.texture.width, www.texture.height), new Vector2 (0, 0));
SmallImage.sprite = Small_Spr;
}
} else {
if(!www.isDone)
{
Debug.Log("WWW IS NOT DONE");
}
if(www.error != null)
{
Debug.Log(www.error);
}
}
}
這段程式碼實際用的時候還是按實際情況再改下吧。類似GetBigImage
和GetSmallImage
兩個函式,其實可以整合成一個函式。寫成兩個函式實在不好看。這裡我只是為了研究下這個功能,所以具體的沒再去優化下。
IOS端
- 在匯出的工程那,新建個OC類,這個類是用來實現功能的。然後看下標頭檔案的程式碼吧!
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface GetImage : UIViewController<UIActionSheetDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate>
+(GetImage*)getImageView;
-(void)CallPhoto;
-(void)RemaoveView;
-(NSString*)GetDate;
-(UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size;
-(void)saveImage:(UIImage *)currentImage withName:(NSString *)imageName;
@end
這裡我定義了三個成員函式和一個類函式,比較重要的一點就是繼承UIViewController
和後面那一串協議。有興趣的可以自己去研究下。
- 然後是這幾個函式的具體實現了,完整程式碼我貼出來得了
//
// GetImage.m
// CamreaTest
//
// Created by Admin on 15/8/27.
// Copyright (c) 2015年 Admin. All rights reserved.
//
#import "GetImage.h"
#define New_Size CGSizeMake(128,128)
@implementation GetImage
static GetImage* _getImageView = NULL;
+(GetImage*)getImageView{
if(_getImageView == NULL){
_getImageView = [[GetImage alloc] init];
}
return _getImageView;
}
-(void)CallPhoto{
//新增檢視控制器,和檢視
UIViewController *_roottemp = UnityGetGLViewController();
[_roottemp addChildViewController:[GetImage getImageView]];
[_roottemp.view addSubview:[GetImage getImageView].view];
UIActionSheet *sheet;
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
sheet = [[UIActionSheet alloc] initWithTitle:@"選擇圖片" delegate:self cancelButtonTitle:@"取消"
destructiveButtonTitle:nil otherButtonTitles:@"拍照",@"從相簿選擇", nil];
}
else{
sheet = [[UIActionSheet alloc] initWithTitle:@"選擇" delegate:self cancelButtonTitle:nil destructiveButtonTitle:@"取消" otherButtonTitles:@"從相簿選擇", nil];
}
sheet.tag = 255;
[sheet showInView:self.view];
}
-(NSString*)GetDate{
NSDate * senddate=[NSDate date];
NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init];
[dateformatter setDateFormat:@"yyyyMMddHHmmss"];
NSString * locationString=[dateformatter stringFromDate:senddate];
return locationString;
}
- (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size{
// 建立一個bitmap的context
// 並把它設定成為當前正在使用的context
UIGraphicsBeginImageContext(size);
// 繪製改變大小的圖片
[img drawInRect:CGRectMake(0, 0, size.width, size.height)];
// 從當前context中建立一個改變大小後的圖片
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
// 使當前的context出堆疊
UIGraphicsEndImageContext();
// 返回新的改變大小後的圖片
return scaledImage;
}
-(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (actionSheet.tag == 255) {
NSUInteger sourceType = 0;
// 判斷是否支援相機
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
if (buttonIndex == actionSheet.cancelButtonIndex)
{
return;
}
switch (buttonIndex) {
case 0:
// 相機
sourceType = UIImagePickerControllerSourceTypeCamera;
break;
case 1:
// 相簿
sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
break;
}
}
else {
if (buttonIndex == 0) {
return;
} else {
sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
}
}
// 跳轉到相機或相簿頁面
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.allowsEditing = YES;
imagePickerController.sourceType = sourceType;
imagePickerController.supportedInterfaceOrientations;
[self presentViewController:imagePickerController animated:YES completion:^{}];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:^{}];
UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
/* 此處info 有六個值
* UIImagePickerControllerMediaType; // an NSString UTTypeImage)
* UIImagePickerControllerOriginalImage; // a UIImage 原始圖片
* UIImagePickerControllerEditedImage; // a UIImage 裁剪後圖片
* UIImagePickerControllerCropRect; // an NSValue (CGRect)
* UIImagePickerControllerMediaURL; // an NSURL
* UIImagePickerControllerReferenceURL // an NSURL that references an asset in the AssetsLibrary framework
* UIImagePickerControllerMediaMetadata // an NSDictionary containing metadata from a captured photo
*/
NSString* smallname = [@"Small" stringByAppendingString:[[self GetDate] stringByAppendingString:@".png"]];
[self saveImage:[self scaleToSize:image size:New_Size] withName:smallname];
UnitySendMessage("HeadSelect", "GetSmallImage", [smallname UTF8String]);
[self RemoveView];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:^{}];
[self RemoveView];
}
- (void) saveImage:(UIImage *)currentImage withName:(NSString *)imageName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);//獲取document路徑
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:imageName];//拼接字串 圖片名稱為pic
NSData *imageData = UIImagePNGRepresentation(currentImage);//UIImage到NSData格式轉換
[imageData writeToFile:savedImagePath atomically:NO];//生成圖片
}
//結束後從列表刪除自己
-(void) RemoveView
{
[self removeFromParentViewController];
[self.view removeFromSuperview];
}
@end
先說下
getImageView
吧,我為了在不同的類中獲取到同一個視窗,把他弄成了單例。至於
GetData
這個純粹是我想給圖片命名加上當前日期日期我原來是用XX-XX-XX XX:XX:XX這種格式,圖片也能出來,但是用WWW載入的時候就出問題了。所以還是儘量不要用特殊符號吧!
scaleToSize
和SaveImage
這兩個顧名思義就是縮小圖片到指定大小以及儲存圖片到本機。
(PS:原來有考慮過UnitySendMessage直接傳NSData,不過沒搞定O。O,哪位大牛如果搞定了,希望分享一下。)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
這兩個函式其實程式碼完全一樣,主要是IOS版本問題,為了相容下低版本,在這裡我把兩個都寫了,不知道有沒什麼更好的辦法。(測試過,用新版的就可以了,我把原來的刪除了)
imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
- 你選中圖片的時候呼叫的。
- 再新建個類,這個類比較簡單就一個函式
void _GetImage(){
[[GetImage getImageView] CallPhoto];
}
這樣就搞完了,如果有什麼做的不好的地方,希望大家幫我指出來。
(小改了下,感覺getImageView,改完不需要弄成單例了,有空的時候我會去試下)