質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Cocoa

CocoaはMac OS X用のアプリケーションを構築する為の主要なフレームワークのひとつです。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2735閲覧

ローカルに保存した画像ファイルをNSImageとして表示したい

b150005

総合スコア2

Cocoa

CocoaはMac OS X用のアプリケーションを構築する為の主要なフレームワークのひとつです。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/10/21 13:37

編集2021/10/21 13:42

前提・実現したいこと

SwiftとCocoaフレームワークを利用して、macOS向けのアプリケーションを開発しております。
ユーザが指定した絶対パスに格納された画像ファイル(.gif)を、NSImageViewの子ビューとして表示させたいです。

なお、NSImageViewについて、StoryboardからAnimatesおよびEditableプロパティにはチェックを入れております。

また、プロジェクトフォルダ内に同じ画像ファイルを配置し、StoryboardからImage Cellのimageプロパティとして画像ファイルをファイル名で指定すると表示されることは確認できております。

発生している問題・エラーメッセージ

NSImageViewのimageプロパティにURLを内部的に保持するNSImageオブジェクトをセットしましたが、表示されません。
また、URLの整合性や生成したNSImageのisValidプロパティを確認してみたところ、NSImage#isValid == falseとなっていたことから、NSImageインスタンスの生成の仕方が間違えているとは思うのですが、どう直せば有効なNSImageインスタンスが生成でき、最終的にNSImageViewに反映できるのかが分かりません。

該当のソースコード

swift

1/// アプリケーションウィンドウのコンテンツを管理するクラス 2class ViewController: NSViewController { 3 4 @IBOutlet weak var imageView: NSImageView! 5 6 override func viewDidLoad() { 7 super.viewDidLoad() 8 9 let isExists: Bool = FileManager.default.fileExists(atPath: "/Users/b150005/Downloads/sample1.gif") 10 print(isExists) // 確認用 11 print(NSImage(byReferencing: URL(fileURLWithPath: "/Users/b150005/Downloads/sample1.gif")).isValid) // 検証用 12 13 if (isExists) { 14 // NSImageViewに表示させる画像(NSImage)の指定 15 imageView.image = NSImage(byReferencing: URL(fileURLWithPath: "/Users/b150005/Downloads/sample1.gif")) 16 } 17 } 18}

実行結果

true false

試したこと

とりあえずNSImage#isValidtrueとなるように以下を試しました。

①NSImageのイニシャライザを変えてみる
NSImage(contentsOfFile: "file:///Users/b150005/Downloads/sample1.gif")?.isValid
nil

NSImage(contentsOf: URL(fileURLWithPath: "file:///Users/b150005/Downloads/sample1.gif"))?.isValid
nil

NSImage(byReferencing: URL(string: "file:///Users/b150005/Downloads/sample1.gif")!).isValid
false

②URL文字列を変えてみる
・"file:///Users/b150005/Downloads/sample1.gif"
・"/Users/b150005/Downloads/sample1.gif"
→ 一部のイニシャライザを除き変化なし
URL(string:)では下記の(ランタイム)エラーメッセージが表示されました。

nsurlconnection finished with error 1002

補足情報(FW/ツールのバージョンなど)

OS: macOS Big Sur
CPU: Intel Core i7(3.8GHz@8 core)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/10/23 20:03

回答を放置されていますがどうかされましたか?質問の意図と異なり解決に関係ない回答である場合はその旨ご指摘頂き質問にご反映下さい。
guest

回答1

0

ベストアンサー

原則、NSSearchPathForDirectoriesInDomains を使ってディレクトリパスを取得し、それにファイルまでのパスを付け足すようにします。

.downloadsDirectory で「ダウンロード」ディレクトリを、.userDomainMask でアプリを実行しているユーザのディレクトリとして検索する事を指定します。最後の true~/... というパスのチルダ ~ を絶対パスとして展開するかどうかです。デバッグする上では展開しておいた方が明確です。

swift

1override func viewDidLoad() { 2 super.viewDidLoad() 3 4 if var path = NSSearchPathForDirectoriesInDomains( 5 .downloadsDirectory, .userDomainMask, true 6 ).first { 7 path.append("/sample1.gif") 8 9 if let image = NSImage(contentsOfFile: path) { 10 self.imageView.image = image 11 } else { 12 print("画像ファイルがありませんでした") 13 } 14 } 15}

また、アクセスするディレクトリのパーミッションを要求するのを忘れないで下さい。

イメージ説明

投稿2021/10/21 14:37

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

b150005

2021/10/24 03:55

お返事が遅くなって申し訳ありませんでした。 ycv57u6yさんが仰っていた通りに試してみると、無事表示させることができました。 FileManagerに`NSSearchPathForDirectoriesInDomains(_:_:_:)`というメソッドがあるんですね.. FileManagerについてもう少し勉強して、分かった範囲で情報を追記したいと思います。 迅速なご回答をいただき助かりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問