Archive for the ‘Tips’ Category

アイデアを生み出す13の方法

木曜日, 1月 13th, 2011
このエントリーを含むはてなブックマークはてなブックマーク - アイデアを生み出す13の方法

 


 
 

アイデアを出すときには、自分の中にある情報雲とでも言うべき”もやもや”っとしたモノから数カ所をちぎりとり、型を変えて、見方を変えて、姿をかえて、そして本質をつくりだす。その火種となる情報雲を絶やさないように・・・。
 
 
 

ちょっと慣れてきた人の為のハテブの使い方

効率よく人気記事を探すためには、はてなブックマークの人気エントリーや注目エントリーを利用するのが一番便利だと思います。このサイトでは、これらのエントリーだけでなく、一歩踏み込んだ使い方まで解説されているので、はてなブックマークをさらに利用したい方にはオススメです!
 
 
 

今さら聞けない?初心者に送る「Twitter」の始め方・使い方

インスタントでライトなコミュニケーションはもとより、研究や技術といった深〜い情報の交換までできてしまう優れもの。ただ、RTや@や#など、使われる用語が特殊なため、少し敷居が高いと感じてしまう人も多いはず。そこで、このサイトを読んで、Twitterの世界へ飛び込んでみてはいかがでしょう?
 
 
 

ウェブを保存して後で読む「Instapaper」のある快適生活の始め方

ウェブの情報を保存しておいて、後からモバイルデバイスで読むことができるようにする「Instapaper」。オフラインでも閲覧可能なため、大量の情報を読みこなすには必須のアイテムです。このサイトではInstapaperの設定方法から使い方まで詳しく説明されています。
 
 
 

整理するということは、ものに属性をつけ、カテゴリで縛ること。そうやって、整理していけば、どんどん自由度が失われて、どんどん不自由に、そしてどんどん明快になっていく。すべてを曖昧なまま、そして、自由なままにしておきたい。そうすれば、いろんな物がいろんな次元で繋がり始める。
 
 

机の上も頭の中もスッキリ!?Evernoteの使い方みつけたよ!

Evernoteは気に入ったもの、気になったもの、ピンと来たもの、何でも全て放り込める道具箱のような存在。このサイトでは、そんなEvernoteの様々な利用方法が紹介されています。
 
 
 

素敵BOXという名のフォルダ

Evernoteも便利なんですけれども、やはりフォルダの手軽さには及びません。僕のデスクトップの左上にはいつも素敵BOXという名のフォルダがあって、綺麗なものを全部キャプチャしてほうりこんでいます。
 
 
 

RHODIA

メモ帳といえば、Windows・・・じゃなくてRHODIAのメモ帳です。このメモにとにかくアイデアを走り書きしています。方眼紙になっているので、図を描きやすいのが特徴ですね。
 
 
 

 
電車でぼ〜っと流れる景色を眺めているとき、風呂でぼ〜っと天井を眺めているとき、そんな時にアイデアは降ってくる、決して必死で考えているときには得られない素晴らしいインスピレーションが。たまにはゆとりを持って映画や本やアニメを見るのも一興です。
 
 
 

ヒックとドラゴン

2010年に見た映画ではイチオシ。いつも映画は予告編が一番面白い!と言っているのですが、予告編よりも遥かに面白かった希少な映画。主役のドラゴンが猫にしか見えない(笑)猫好きなら絶対見とけ、的な映画です。
 
 
 

イリヤの空、UFOの夏

「イリヤの空、UFOの夏」は僕が初めて読んだライトノベルス。毎年、夏になると無性に読みたくなる本です。とにかくこの作家さん、情景を書くのが上手くて本を読んでいても映像として入ってくるのがすごい!
 
 
 

電脳コイル

日本のAR(Augmented Reality)研究者でこのアニメを知らなかったらモグリだろ?っていうくらい有名なアニメ。Webとバーチャルの世界に生きる現代人に痛快なメッセージを届けてくれます。そしてなにより、素晴らしく面・白・い!!
 
 
 

先人のアイデアにインスパイアされてみよう。 優れたものを見たとき、確実に自分の中の想像力、もしくは発想力の根源がざわつく。それは聞こえないほど微小かもしれない、触れられないほど微細かもしれない。でもきっと。
 
  
 

インターネットミュージアム

家の近くにある美術館や博物館を検索できるほか、ジャンル別でイベント情報なども検索したり、タイムリーなニュースを読むことも出来ます。
 
 
 

Klimt HD

グスタフクリムトの画集がiPadで鑑賞できるアプリ。他にもゴッホの作品を見ることが出来るVincent van Gogh – Classic Painters Galleryや、1000以上の有名な芸術家による4万点の絵画や彫像を鑑賞することができるArt Authority for iPadなどのアプリもあります。
 
  

画像処理に使えるUIImageのTips10個

木曜日, 1月 6th, 2011
このエントリーを含むはてなブックマークはてなブックマーク - 画像処理に使えるUIImageのTips10個

 
 
 
(1) 画像をUIImageに読み込む

指定したファイルから画像を読み込み、UIImageに格納するためにはUIImageのクラスメソッドであるimageNameメソッドを使います。このメソッドはinitWithContentsOfFileよりも高速です。

//画像を読み込む
UIImage *image = [UIImage imageNamed:@"test.jpg"];

 
 
 
 
(2) 画像をファイルパスから読み込む

ファイルパスを指定して画像を読み込むためには、NSBundleクラスを用いてパスを作成し、そのパスをinitWithContentsOfFileの引数にしてわたします。ただし、initWithContentsOfFileで作成したUIImageの描画は非常に遅いので注意。

NSString *filePath 
= [[NSBundle mainBundle] pathForResource:@"test" ofType:@"jpg"];
	
UIImage *img
= [[UIImage alloc] initWithContentsOfFile:filePath];

 
[参考]

  • UIImage#imageNamed:は読み込みも描画もUIImage#imageWithContentsOfFile:やそれ以外のメソッドより5~6倍速い
  • Sun Limited Mt. UIImage#ImageWithContentsOfData: などは描画が激遅
  •  
     
      
     
     
    (3) UIImageをカメラロールに保存する

    作成したUIImageをカメラロールに保存するためにはUIImageWriteToSavedPhotosAlbum関数を利用します。引数には保存画像、デリゲート、完了を知らせるコールバック関数を指定します。

    このメソッドで指定した画像はJPG形式に変換され保存されるため、画質の劣化は避けられません。画質は93%の圧縮画像になるようです。今のところ、このメソッドがカメラロールに保存する唯一の方法です。

    - (void) finishExport:(UIImage *)image
    didFinishSavingWithError:(NSError *)error
    contextInfo:(void *)contextInfo
    {
      NSLog(@"save image successfully"); 
    }
    
    UIImageWriteToSavedPhotosAlbum(image, self, @selector(finishExport:didFinishSavingWithError:contextInfo:),
    nil);
    
    

    [参考]

  • iPhoneアプリ開発ブログ UIViewのスクリーンショットの画質を良くしたい
  • Unnamed Red UIImage をカメラロールに保存する
  •  
     
     
     
    (4) UIImageを拡大縮小する

    第一引数に元画像を、第二引数にリサイズ後のサイズを渡すことで、画像のアスペクトを保持したままリサイズを行い、その画像を返してくれるメソッド。アスペクトを保持するため、始めの4行で拡大率を固定している。

    リサイズを行うため、まずはUIGraphicsBeginImageContextメソッドで指定サイズのグラフィックスコンテキストを取得し、そこに画像を描画する。グラフィックスコンテキストに描画された画像を再びUIGraphicsGetImageFromCurrentImageContextメソッドで取得してUIImage型に再合成している。
     

    - (UIImage*)resizedImage:(UIImage *)img size:(CGSize)size
    {
    	CGFloat widthRatio  = size.width  / img.size.width;
    	CGFloat heightRatio = size.height / img.size.height;
    	CGFloat ratio = (widthRatio < heightRatio) ? widthRatio : heightRatio;
    	CGSize resizedSize = CGSizeMake(img.size.width*ratio, img.size.height*ratio);
    	
    	UIGraphicsBeginImageContext(resizedSize);
    	
    	&#91;img drawInRect:CGRectMake(0, 0, resizedSize.width, resizedSize.height)&#93;;	
    	UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext();
    	
    	UIGraphicsEndImageContext();
    	
    	return resizedImage;
    }
    &#91;/cpp&#93;
    
    &#91;参考&#93;
    <li><a href="http://i.studio23c.com/?p=612">iPhoneメモ UIImageの縮小 〜比率を保持して/カテゴリでメソッドを追加編〜</a></li>
     
     
     
     
    <span style="font-size:large;color:RoyalBlue"><strong>(5) UIImageを回転させる</strong></span>
    
    <a href="http://iphone.moo.jp/app/wp-content/uploads/rotateuiimage.jpg"><img src="http://iphone.moo.jp/app/wp-content/uploads/rotateuiimage.jpg" alt="" title="rotateuiimage" width="382" height="102" class="alignnone size-full wp-image-803" /></a>
    
    第一引数に元画像を、第二引数に回転角度を渡すことで、回転した画像を返してくれるメソッド。回転角度には90, 180, 270度のみ指定可能。
    
    こちらも画像の拡大縮小と同様、グラフィックスコンテキストに一度描画を行い、そのグラフィックスコンテキストに対して回転処理をほどこした後、UIImage型に再合成しています。
     
    [cpp]
    - (UIImage *) rotateImage:(UIImage *)img angle:(int)angle
    {
    	CGImageRef imgRef = [img CGImage];
    	CGContextRef context;
    	
        switch (angle) {  
    		case 90:  
    			UIGraphicsBeginImageContext(CGSizeMake(img.size.height, img.size.width));					
    			context = UIGraphicsGetCurrentContext();  			
    			CGContextTranslateCTM(context, img.size.height, img.size.width);  
    			CGContextScaleCTM(context, 1.0, -1.0);  
    			CGContextRotateCTM(context, M_PI/2.0);  
    			break; 
    		case 180:
    			UIGraphicsBeginImageContext(CGSizeMake(img.size.width, img.size.height));					
    			context = UIGraphicsGetCurrentContext();  
    			CGContextTranslateCTM(context, img.size.width, 0);  
    			CGContextScaleCTM(context, 1.0, -1.0);  
    			CGContextRotateCTM(context, -M_PI);  
    			break;  
    		case 270:  
    			UIGraphicsBeginImageContext(CGSizeMake(img.size.height, img.size.width));					
    			context = UIGraphicsGetCurrentContext();  
    			CGContextScaleCTM(context, 1.0, -1.0);  
    			CGContextRotateCTM(context, -M_PI/2.0);  
    			break;  
    		default:
    			NSLog(@"you can select an angle of 90, 180, 270");
    			return nil;
        }  
    	
        CGContextDrawImage(context, CGRectMake(0, 0, img.size.width, img.size.height), imgRef);  
        UIImage *ret = UIGraphicsGetImageFromCurrentImageContext();  
        
        UIGraphicsEndImageContext();  
    	return ret;
    }
    
    

    [参考]

  • 琴線探査 iPhoneで画像を回転させて保存するには?
  •  
     
     
     
    (7) UIImageのピクセルにアクセスする

    UIImageに対して独自の画像処理を行う場合には、UIImageのピクセルにアクセスする必要があります。下の例はUIImageのピクセルにアクセスして、画像をグレースケール化しています。

    具体的にはUIImageからCGImage型を経てピクセル配列へと分解し、ピクセルに対して画像処理を行ったあと、分解とは逆の操作を行うことでUIImageまで再合成しています。
     

    	// pixel値の抽出
    	UIImage *img = [UIImage imageNamed:@"test.jpg"];	
    	CGImageRef cgImage = [img CGImage];
    	size_t bytesPerRow = CGImageGetBytesPerRow(cgImage);
    	CGDataProviderRef dataProvider = CGImageGetDataProvider(cgImage);
    	CFDataRef data = CGDataProviderCopyData(dataProvider);
    	UInt8* pixels = (UInt8*)CFDataGetBytePtr(data);
    	
    	// 画像処理(グレースケール化)
    	for (int y = 0 ; y < img.size.height; y++){
    		for (int x = 0; x < img.size.width; x++){
    			UInt8* buf = pixels + y * bytesPerRow + x * 4;		
    			UInt8 r, g, b;
    			r = *(buf + 0);
    			g = *(buf + 1);
    			b = *(buf + 2);
    			UInt8 gray = (77 * r + 28 * g + 151 * b)>>8;
    			*(buf + 0) = gray;
    			*(buf + 1) = gray;
    			*(buf + 2) = gray;
    		}
    	}
    	
    	// pixel値からUIImageの再合成
    	CFDataRef resultData = CFDataCreate(NULL, pixels, CFDataGetLength(data));
    	CGDataProviderRef resultDataProvider = CGDataProviderCreateWithCFData(resultData);
    	CGImageRef resultCgImage = CGImageCreate(
    						   CGImageGetWidth(cgImage), CGImageGetHeight(cgImage), 
    						   CGImageGetBitsPerComponent(cgImage), CGImageGetBitsPerPixel(cgImage), bytesPerRow, 
    						   CGImageGetColorSpace(cgImage), CGImageGetBitmapInfo(cgImage), resultDataProvider, 
    						   NULL, CGImageGetShouldInterpolate(cgImage), CGImageGetRenderingIntent(cgImage));
    	UIImage* result = [[[UIImage alloc] initWithCGImage:resultCgImage] autorelease];
    	
    	// 後処理
    	CGImageRelease(resultCgImage);
    	CFRelease(resultDataProvider);
    	CFRelease(resultData);
    	CFRelease(data);
    

    [参考]

  • sonson@Picture&Software UIImageでピクセルを扱う
  • iPhoneアプリで稼げるのか カメラアプリ系の画像処理をする
  •  
     
     
     
    (8) UIImageでアニメーションを作る

    animation

    UIImageの配列を作成し、それをImageVIewクラスに登録することでアニメーション表示することができます。animationDurationでアニメの実行時間を指定できます。

        NSArray *imageArray = [[NSArray alloc] initWithObjects:
    						 [UIImage imageNamed:@"test.jpg"],
    						 [UIImage imageNamed:@"test2.jpg"],
    						 [UIImage imageNamed:@"test3.jpg"],	
    						 [UIImage imageNamed:@"test4.jpg"],	
    						 [UIImage imageNamed:@"test5.jpg"],	 
    						 nil];
    
        imageView.animationImages = imageArray;
        imageView.animationDuration = 1.0f;
      
        [imageView startAnimating];
    

     

    [参考]

  • UIImageで手っ取り早くアニメーションを作ってしまう方法
  •  
      
     
     
    (9) マスク処理で角丸画像を作成する

    UIImageの画像にマスクをかけるにはCGImageCreateWithMaskメソッドを使用します。引数として与えるマスク画像はCGImageMaskCreateメソッドを使って作成しています。この際、角丸のマスク画像を使用することで、元画像を角丸画像に変換することが出来ます。

    - (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
     
    	CGImageRef maskRef = maskImage.CGImage; 
     
    	CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
    		CGImageGetHeight(maskRef),
    		CGImageGetBitsPerComponent(maskRef),
    		CGImageGetBitsPerPixel(maskRef),
    		CGImageGetBytesPerRow(maskRef),
    		CGImageGetDataProvider(maskRef), NULL, false);
     
    	CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
    	return [UIImage imageWithCGImage:masked];
     
    }
    

      

    [参考]

  • [iOS developer:tips]; How to Mask an Image
  •  
     
     
     
    (10) IplImageとUIImageの相互変換

    opencvuiimage

    ここまでは、UIImageに対して直接処理を行って来ましたが、本格的な画像処理を行う場合にはOpenCVを使ったほうが簡単に行なえます。しかし、iPhoneプログラミングではcvLoadImge関数を使って画像を読み込むことは出来ないので、

    • imageNamedメソッドで画像読み込み
    • UIImage から IplImage型に変換
    • OpenCVで画像処理
    • IplImage から UIImage型に変換して表示

    という流れになります。

    ここでは、UIImageとIplImageの相互変換のプログラムを紹介します。まずはUIImageをIplImageに変換するメソッド。

    - (UIImage *)resizedImageArbitrarily:(UIImage *)img size:(CGSize)size
    IplImage* createIplImageFromUIImage(UIImage* image)
    {
    	// CGImageをUIImageから取得
    	CGImageRef imageRef = image.CGImage;
    	
    	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    	// 一時的なIplImageを作成
    	IplImage *iplimage = cvCreateImage(cvSize(image.size.width,image.size.height), IPL_DEPTH_8U, 4 );
    	
    	// CGContextを一時的なIplImageから作成
    	CGContextRef contextRef = CGBitmapContextCreate(
    													iplimage->imageData, iplimage->width, iplimage->height,
    													iplimage->depth, iplimage->widthStep,
    													colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault);
    	// CGImageをCGContextに描画
    	CGContextDrawImage(
    					   contextRef,
    					   CGRectMake(0, 0, image.size.width, image.size.height),
    					   imageRef);
    	
    	CGContextRelease(contextRef);
    	CGColorSpaceRelease(colorSpace);
    	
    	// 最終的なIplImageを作成
    	IplImage *ret = cvCreateImage(cvGetSize(iplimage), IPL_DEPTH_8U, 3);
    	cvCvtColor(iplimage, ret, CV_RGBA2BGR);
    	cvReleaseImage(&iplimage);
    	
    	return ret;
    }
    

    こちらは逆にOpenCVのIplImageからUIImageに変換するメソッド。

    UIImage* createUIImageFromIplImage(IplImage *image)
    {
    	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    	// CGImageのためのバッファを確保
    	NSData *data =
        [NSData dataWithBytes:image->imageData length:image->imageSize];
    	CGDataProviderRef provider =
        CGDataProviderCreateWithCFData((CFDataRef)data);
    	// IplImageのデータからCGImageを作成
    	CGImageRef imageRef = CGImageCreate(
    										image->width, image->height,
    										image->depth, image->depth * image->nChannels, image->widthStep,
    										colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault,
    										provider, NULL, false, kCGRenderingIntentDefault
    										);
    	// UIImageをCGImageから取得
    	UIImage *ret = [UIImage imageWithCGImage:imageRef];
    	CGImageRelease(imageRef);
    	CGDataProviderRelease(provider);
    	CGColorSpaceRelease(colorSpace);
    	return ret;
    }
    

    [参考]

  • yoshimasa niwa iPhoneでOpenCVを使う方法
  •  

    アプリ名のローカライズ方法

    金曜日, 12月 3rd, 2010
    このエントリーを含むはてなブックマークはてなブックマーク - アプリ名のローカライズ方法

    まずは、Resourceフォルダの中にInfoPlist.stringsという名のファイルを作成します。Xcodeのリソースフォルダ上で右クリック→「追加」→「新規ファイル」を選択、新規ファイル作成画面で左カラムから「その他」→「空のファイル」を作成します。

    infoplist1

    ファイルが追加できたら、このファイルに下のように記述して英語のアプリ名を登録します。

    CFBundleDisplayName = "ColorShadow";  
    

    次に作成したInfoPlist.stringsをローカライズします。まずは、Xcode上でInfoPlist.strings を右クリックして「情報を見る」を選択。

    infoplist2

    画面下にある「ファイルをローカライズ可能にする」をクリックし、表示されたウインドウで一般タグを選択して画面下の「ローカリゼーションを追加」をクリック。

    infoplist3

    追加する言語を選択したら、InfoPlist.stringsのローカライゼーションは完了です。Xcodeに戻ると、InfoPlist.strings左側に三角マークが表示された状態になっていると思います。これをクリックするとEnglishとJapaneseのファイルがドロップダウンされます。

    infoplist4

    この中のJapaneseファイルを選択して、この中に日本語のアプリ名を記載します。

    CFBundleDisplayName = "色影";  
    

    これで、アプリ名をローカライズすることが出来ました。実際にインストールしてみて、ちゃんと日本語でアプリ名が表示されているかどうか、確認してみてください。

    iPhoenでタイマー処理

    日曜日, 11月 28th, 2010
    このエントリーを含むはてなブックマークはてなブックマーク - iPhoenでタイマー処理

    数秒後に実行したい処理がある場合、iPhoneアプリではNSTimerクラスを使うのが常套手段のようです。使い方は、以下のとおり。

    
    -(void)myFunc:(NSTimer*)timer
    {
    }
    
    -(void)someFunc
    {
        NSTimer* timer;
        timer = [NSTimer scheduledTimerWithTimeInterval:1 
        target:self 
        selector:@selector(myFunc:)
        userInfo:nil 
        repeats:YES];
    }
    

    scheduledTimerWithTimeInterval:target:selector:userInfo:repeatsメソッドの引数は順番に、タイマーのインターバル、コールバック先、コールバック関数名、パラメータ、繰り返しのON・OFFになっています。

    ただ、数秒後に一度だけ関数を実行したい場合には、もう少し便利な performSelector:withObject:afterDelay:メソッドが存在します。このメソッドの引数は順番に、コールバック関数、引数、何秒後に実行するか、となっています。

    使い方はいたって簡単で、以下のとおり。

    -(void)myFunc:(NSTimer*)timer
    {
    }
    
    -(void)someFunc
    {
    [self performSelector:@selector(myFunc) withObject:nil afterDelay:1.0];
    }
    

    UIActivityIndicatorViewの動作

    土曜日, 11月 27th, 2010
    このエントリーを含むはてなブックマークはてなブックマーク - UIActivityIndicatorViewの動作

    UIActivityIndicatorViewを使用する際に、同一スレッド内で開始処理、停止処理を記述しても、インディケータは動作してくれません。

    具体的には、

    -(void) myFunction
    {
    [indicator startAnimating];
    
    // 処理
    
    [indicator stopAnimating];
    }
    

    のように記述してもUIActivityIndicatorViewが思い通りに動作することはありません。正しくUIActivityIndicatorViewを動作させるためには、startAnimatingとstopAnimatingを別スレッドでコールしてやる必要があります。

    そこで、performSelectorInBackground:withObjectメソッドを使って別スレッドを生成し、その中で処理を行うことで、UIActivityIndicatorViewを正しく動作させることが出来るようになります。参考プログラムを下に書いておきます。

    -(void) anotherFunction
    {
        NSAutoreleasePool *pool;
        pool = [[NSAutoreleasePool alloc] init];
    
     // 処理
    
        [indicator stopAnimating];
        [pool drain];
    }
    
    -(void) myFunction
    {
        [indicator startAnimating];
        [self performSelectorInBackground:
             @selector(anotherFunction) 
             withObject:nil];
    }