你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> IOS關於從照相機獲取圖片的問題,初步探究通過攝像頭實現顏色與形狀識別機制==

IOS關於從照相機獲取圖片的問題,初步探究通過攝像頭實現顏色與形狀識別機制==

編輯:IOS開發綜合

ios通過攝像頭獲取特定數據

文字太小可通過command ‘+’調大字體,溫馨提示。
注釋: 由於最近項目需求,需要一個能夠實現對攝像頭圖片獲取其中部分內容的功能,類似於二維碼掃描。但是只需要獲取特定位置的像素塊進行簡單計算即可,所以聽上去還是很簡單的,但是經過實踐,發現,現實似乎與想象中不一樣,由於攝像頭拍到的數據,采用的是QZ(也就是CG框架)進行繪制,所以涉及到坐標系與frame的坐標系不一致的問題。
1:嘗試直接拿到攝像頭數據,先輸出看下。 code: 代碼略。
總結: 直接使用攝像頭數據再用imageView的方式顯示出來的時刻,我們發現,數據是正確的==。所見即所得的方式。 需要注意的是: 當圖片是橫向拍攝的時刻,我們可以看到,相機會自動將圖片進行90度旋轉,也就是說,系統在你橫向拍攝的時刻,會自動將圖片旋轉90度,滿足你正常情況下的觀看。
所以: 我們使用imageView對拿到的數據進行展示的時刻,數據並沒有顛倒的現象。為了防止出現這個現象的原因是出於imageView的內部實現,我們使用CgimageRef的方式,再次驗證 從攝像頭拿到的數據真的和我們所看到的一樣嗎?
code:

CGImageRef oldImageRef=image.CGImage;

UIImage* newImage=[UIImage imageWithCGImage:oldImageRef];

注釋:
在這裡,我們只是對拿到的Image對象,先轉換成了CGimage,再使用UIImage的方法得到新的Image對象。
結果:我們發現,得到的圖像果然就是旋轉90度的圖片,而不再是原圖了。

UIImage* newImage=[UIImage imageWithCGImage:oldImageRef scale:.1 orientation:UIImageOrientationRight];

使用上面的語句,可以將圖像旋轉90度變成我們需要的樣子。

思考:
這麼簡單的變化中,圖片會不會丟失數據? ---------

NSData* data=UIImageJPEGRepresentation(image, 0);

NSLog(@"%lu",(unsigned long)data.length);

\
還好,數據沒有丟失。既然數據沒有丟失,那麼我們應該可以獲取到其中特定的一塊數據得出,再顯示出來才對。
問題來了: 我們要獲取某一塊數據的內容,我們應該怎麼傳遞rect呢?因為我們默認的rect與CG的坐標系並不同。是否需要轉換呢?



1:我們先試一下,先把數據轉過來,再從裡面拿一部分. code:

CGImageRef imageRef=image.CGImage;

CGImageRef newimage=CGImageCreateWithImageInRect(imageRef, rect);


結果發現: 拿到的數據還是傾斜了90度。也就是說,我們上面對數據這樣的轉換其實根本沒有起到作用,數據在底層存儲的方式就是使用CG的坐標系存儲的。
經過試驗發現,[UIImage imageWithCGImage:oldImageRef scale:.1 orientation:UIImageOrientationRight]中,對orientation的改變,不會對我們的實驗結果產生任何影響。 也就是說,這個方法,其實並沒有對底層的數據進行操作,而只不過是在初始化新的UIImage的時刻,對底層像素的讀取,orientation不同,方向也不同而已。
思考:
因為,我們使用上面的方法,並沒有操作到底層的像素矩陣,也就是我,我們如果想要解決這個問題,有兩種方式, 1:將底層數據矩陣轉換成我們需要的對應坐標系的內容。 這也就是CTM轉換。 將Image對象內部數據進行轉換。 code:

- (UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation
{
    long double rotate = 0.0;
    CGRect rect;
    float translateX = 0;
    float translateY = 0;
    float scaleX = 1.0;
    float scaleY = 1.0;
    
    switch (orientation) {
        case UIImageOrientationLeft:
            rotate = M_PI_2;
            rect = CGRectMake(0, 0, image.size.height, image.size.width);
            translateX = 0;
            translateY = -rect.size.width;
            scaleY = rect.size.width/rect.size.height;
            scaleX = rect.size.height/rect.size.width;
            break;
        case UIImageOrientationRight:
            rotate = 3 * M_PI_2;
            rect = CGRectMake(0, 0, image.size.height, image.size.width);
            translateX = -rect.size.height;
            translateY = 0;
            scaleY = rect.size.width/rect.size.height;
            scaleX = rect.size.height/rect.size.width;
            break;
        case UIImageOrientationDown:
            rotate = M_PI;
            rect = CGRectMake(0, 0, image.size.width, image.size.height);
            translateX = -rect.size.width;
            translateY = -rect.size.height;
            break;
        default:
            rotate = 0.0;
            rect = CGRectMake(0, 0, image.size.width, image.size.height);
            translateX = 0;
            translateY = 0;
            break;
    }
    
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    //做CTM變換
    CGContextTranslateCTM(context, 0.0, rect.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextRotateCTM(context, rotate);
    CGContextTranslateCTM(context, translateX, translateY);
    
    CGContextScaleCTM(context, scaleX, scaleY);
    //繪制圖片
    CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);
    
    UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
    
    return newPic;
}

結論:

這裡的解決方案,就是對底層像素矩陣進行裝換之後,在對裡面數據截取一部分。可以解決截取部分內容的問題。

-------------------

2:解決方案二:就是對rect進行裝換,根據數據底層,進行rect的轉換。


  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved