1. 程式人生 > >Unity3D,獲取相簿圖片,手機拍照

Unity3D,獲取相簿圖片,手機拍照

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); } } }

這段程式碼實際用的時候還是按實際情況再改下吧。類似GetBigImageGetSmallImage兩個函式,其實可以整合成一個函式。寫成兩個函式實在不好看。這裡我只是為了研究下這個功能,所以具體的沒再去優化下。

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載入的時候就出問題了。所以還是儘量不要用特殊符號吧!

  • scaleToSizeSaveImage這兩個顧名思義就是縮小圖片到指定大小以及儲存圖片到本機。
    (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,改完不需要弄成單例了,有空的時候我會去試下)