FC2ブログ

頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


サイズを変更したNSImageオブジェクトを画像ファイルとして出力する

NSImageViewオブジェクトのサイズについて
↑この続き。

NSImageオブジェクトを画像ファイルとして保存したい。

まずNSImage、NSImageViewにそれぞれサイズを指定でき、画面上ではそのサイズが反映されることを確認する。
例えば、下のようなコード。元画像は500x344のPNG画像。
{
    float scale = 0.5;
    NSImage *nsimage = [NSImage imageNamed:@"img500x344png.png"];
    nsimage.size = NSMakeSize(nsimage.size.width*scale, nsimage.size.height*scale);
    
    NSImageView *imageView = [NSImageView imageViewWithImage:nsimage];
    imageView.frame = NSMakeRect(0, 0, nsimage.size.width, nsimage.size.height);
    [self.view addSubview:imageView];
}
ここではNSImageオブジェクトのサイズを変えてるけど、NSImageVIewオブジェクトのframeプロパティのサイズ部分を変更しても同じように表示サイズを変えることができる(※1)。

元画像と縮小した画像を表示

↑オリジナルと縮小した画像を重ねて表示している。なお、macOSなので左下が原点。


この”縮小した”画像をPNG画像として保存(※2)し、その画像ファイルの情報を確認すると、、、

ファイル情報のスクショ

↑サイズは縮小されてはいなくて、オリジナルの画像サイズのままだ。
NSImage、NSImageViewオブジェクトのどちらのサイズをいじっても同じ結果になる。

機械学習などで使いたいから本当に縮小された画像データが欲しい、という場合はそれ相応の処理が必要になる。


※1 上記の方法でNSImageのサイズを変更するとキャッシュされたオブジェクトのサイズも変更されるので注意。他ファイルで同じ画像からNSImageオブジェクトを作成するとすでになぜかサイズがオリジナルと違う?!なんてことに。

※2 NSImageオブジェクトを画像で保存する方法はこちら
macOSでSCNView→png画像を作成、保存する


NSImageViewオブジェクトのサイズについて

macOSアプリ用プロジェクトで拡張子が異なる同名の画像を認識しない
↑この続き、というかこの流れで。

macOSアプリでプロジェクトに入れてある画像ファイルからNSImageオブジェクトを作成し、NSImageViewとして表示する。
以下のようなコードを書いたとする。
{
    NSImage *nsimage = [NSImage imageNamed:@"img500x344png.png"];
    NSAssert(nsimage, @"nsimage is nil");
    NSLog(@"nsimage w,h = [%f,%f]",nsimage.size.width, nsimage.size.height);
    
    
    NSImageView *imageView = [NSImageView imageViewWithImage:nsimage];//—(1)
    NSLog(@"imageView w,h = [%f,%f]",imageView.frame.size.width, imageView.frame.size.height);//—(2)
    NSAssert(imageView, @"imageView is nil”);//—(3)

    [self.view addSubview:imageView];//—(4)
}
↑前半のNSImageオブジェクト作成は前記事通り。
(1)で画面に表示するためにNSImageオブジェクトからNSImageViewオブジェクトを作成する。
(2)で作成されたNSImageViewオブジェクトのサイズを確認すると
// imageView w,h = [0.000000,0.000000]
となり、値がない。
(3)けれどオブジェクトは生成されているのでNSAssertで停止はしない。
(4)画面に表示させるつもりが、何も表示されない。

そう、これだと画像は表示されない。

imageViewにはデフォではサイズは入らないらしいので自分で入れておく必要がある。
{
   imageView.frame = NSMakeRect(x, y, nsimage.size.width, nsimage.size.height);
}
↑frameプロパティを設定しておくと意図通り画面に表示される。

NSImageオブジェクトから作成してるんだから、デフォでNSImageのサイズを入れておいてくれたらいいのにな、と言っても仕方ないので忘れないように入れよう。


Xcode 10.1
macOS Mojave 10.14.1





macOSアプリ用プロジェクトで拡張子が異なる同名の画像を認識しない

NSImageについて確認したいことがあったので、macOSアプリで画像を扱おうと思ったら読み込みができないので悩んだ。

Xcodeに入れた2枚の画像ファイル

↑まずこういう2枚の画像を用意した。同名で拡張子がjpgとpngの2枚だ。これをXcodeに入れておく。

XcodeのTarget Membership指定部分

↑もちろんどちらの画像もTarget Membershipでプロジェクトに追加している。
{
    NSImage *nsimage = [NSImage imageNamed:@"img500w.jpg”];//JPEG画像
    
    NSAssert(nsimage, @"nsimage is nil");
    NSLog(@"w,h = [%f,%f]",nsimage.size.width, nsimage.size.height);
}
↑この状態でJPEG画像を読み込もうとすると
Failed to set (contentViewController) user defined inspected property on (NSWindow): nsimage is nil
↑このようなエラーがNSAssertにより吐き出されアプリは停止する。

ファイル名間違えてないしちゃんとTargetに追加してるし、、、?と思って試しにもう片方のPNG画像をTargetから外したら
w,h = [500.000000,344.000000]
↑ちゃんと読み込むことができた。
逆も同じ。
どうやら同名の画像ファイルはだめらしい、、、😳

ちなみにNSAssertがなければ
w,h = [0.000000,0.000000]
↑画像はnilだが落ちることなく数値はゼロとしてコードは進んでいく。怖いなあ。ちゃんとAssert入れないとダメだな。


なお、以上はmacOS向けプロジェクトの話なのだが、iOS向けプロジェクトでも同じなのか確認した。
{
    UIImage *uiimage = [UIImage imageNamed:@"img500w.jpg"];
    NSAssert(uiimage, @"uiimage is nil");
    NSLog(@"w,h = [%f,%f]",uiimage.size.width, uiimage.size.height);
}
↑NSImageをUIImageにしただけなのだが、こちらは同名で異なる拡張子の画像ファイルは問題なく扱うことができた。


ということでまとめると、
macOSアプリ開発では同名で異なる拡張子の画像ファイルに注意
NSAssertをちゃんと使おう
ってとこか。


Xcode 10.1
iOS 12.1
macOS Mojave 10.14.1





iPhone XS Maxでマインクラフトをプレイする時にホームバーが邪魔

最近iPhone 7 PlusからXS Maxに機種変更し、さっそくマイクラがどんな感じなのかプレイしてみたのですが、、、

iPhone XS Maxのマイクラプレイ画面

↑iPhone XS Maxだと、ホームバーが微妙な位置に。数字を隠してるやん!

こういうiPhone X系の画面下部にある横棒。ホームバーとかホームインジケーターとか言うそうな。
プレイ中邪魔なので、隠す方法が設定とかに当然あるんだよな?と思って調べたら、、、iOSにそういう機能はないっぽい。

ただ、開発側でそういうことはできるらしい(※)。つまり開発元のMojangがアップデートで修正してくれたらいいんだけど、これってiPhone Xの時から問題になってそうだから、つまりこの1年間ずっと放置というか修正するつもりはないってことだよな。


苦肉の策がマイクラアプリ側での設定。

マインクラフトのタイトル画面

↑ゲーム開始画面での「設定」をタップ。ゲーム開始後にも「設定」はあるけど、開始後だとこの設定はできない。

マイクラの設定画面

↑「ビデオ」をタップし、「画面のセーフエリアを変更」をタップ。

マイクラのセーフエリア設定画面

↑するとスライドさせることで「セーフエリア」を変更できる。これを左にスライドさせると(おそらく)必要な情報類の表示エリア(画面四隅にマークがある)が小さくなる。
どのくらいがいいのかわからないけど、62.7くらいだと、、、

セーフエリア設定後のマイクラのプレイ画面

↑このような表示となり、ホームバーがアイテム数を隠さなくなった。タップによるアイテム選択も問題なし。

大きなチェストの中身を見ているスクショ

↑もっとも、今まで大きなチェストの中身は1画面の高さ内に入っていたのが、切れてしまいスクロールさせる必要がある、、、

せっかく画面が大きくなったはずなのになんだかなあ。

MojangなりiOSが対応してホームバーを隠せるようになることを切に願います。



※参考サイト
iPhone XのHome Indicatorの表示/非表示を制御する | DevelopersIO



iPhone X系の背面デュアルカメラで「電脳コイル」ごっこがしたい

iPhoneには背面に広角と望遠のレンズを持つ機種があるが、この二つのカメラから同時に動画を得たいと思いいろいろと試してみた。
iPhone 7,8のPlusだと二つのレンズが(縦に持った場合)横だったが、iPhone X系から縦に並ぶようになった。
つまり、これをLandscapeにするとカメラは横に並ぶ。
この二つのカメラからの動画をそれぞれ並べ、VRゴーグルで見ると風景が立体に見えるはず(もちろん一般に販売されてるVRゴーグルにはiPhoneの背面カメラ用の穴なんてないから穴を開ける必要がある)。
さらにARKitで現在のカメラ位置や姿勢を得て、現実の風景にSceneKitで物体を重ねて表示させたら「電脳コイル」ごっこができるんじゃね?!

VRアプリのスクリーンショット

↑これは以前リリースしたiOSアプリでVRゴーグルで使うものなんだけど、こんな感じで左右微妙に違うCGのオブジェクトを表示されれば、景色もCGも立体で見ることができる!デンスケが俺の部屋をうろうろと歩いたりするんだ!
APPLEもそのためにカメラの位置を変更したんだよね!
などと妄想したのだった。


デンスケのぬいぐるみ

↑ちなみにデンスケというのは「電脳コイル」ってアニメに出てくるキャラで画像はそのぬいぐるみ。



そんなわけで二つの背面カメラからのビデオ情報を得たいのだが、、、

- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection;
↑AVCaptureVideoDataOutputSampleBufferDelegateのこのメソッドが双方のカメラごとにコールされたらなんとかなるはずだ。sampleBufferから画像は生成できるから。

基本的にはAVCaptureSessionオブジェクトに、AVCaptureDeviceInputオブジェクトとAVCaptureVideoDataOutputオブジェクトをaddするので、これらをカメラごとに複数用意するなどいろいろ試行錯誤したのだが、、、

実行結果スクショ

↑二つ作成したAVCaptureVideoDataOutputオブジェクトのポインタをログで確認。
上記delegateメソッド内でコールされてるのはどっちのかを確認している。なおAVCaptureVideoDataOutputはAVCaptureOutputのサブクラス。
よく見ると最初だけ片方のoutputが来てるが、後はずっともう片方のデータしか来ていない。

現在のiOS 12.1では無理っぽい。それらしいプロパティ、メソッドなさそうだし。

iPhone背面のデュアルカメラで同時に写真を得る
↑ここでも書いてるけどデュアルカメラで同時に静止画が撮影できるようになったのがiOS 11.0からだしなあ。まだ時間かかるのかもしれない。

ios - iPhone 7 Plus - AVFoundation dual camera - Stack Overflow
↑ビデオは無理だよって書いてる。公式フォーラムの”中の人”ではないので参考までに。



iOS 12.1
Xcode 10.1




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.

FC2Ad