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

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

新規登録して質問してみよう
ただいま回答率
86.02%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

相対パスみたいな画像ファイルを表示する方法

samakimi
samakimi

総合スコア3

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

2回答

0グッド

0クリップ

531閲覧

投稿2022/11/14 11:54

編集2022/11/15 11:23

前提

Windows 10 の Visual Studio 2022 で の.NET6のFrameworkでWindows Forms アプリです。

Form上に画像を一覧で表示するため下のコードによって行っている。
Pictureboxを使って、座標を指定していろんな画像を表示させたいのですが、

フォルダーのパスで読み込む画像を指定すると、
自分のパソコンでは動くけど、
作製したプロジェクトのフォルダーごと他人のパソコンで実行すると動かなくなったので、
何か良い方法はありませんか?

C#

1 /// <summary> 2 /// 画像を一覧で表示するために行っている 3 /// </summary> 4 public class Item 5 { 6 /// <summary> 7 /// ID 8 /// </summary> 9 public int id { get; set; } 10 11 /// <summary> 12 /// 商品の名前 13 /// </summary> 14 public string Name { get; set; } 15 16 /// <summary> 17 /// 画像 18 /// </summary> 19 public string Image { get; set; } 20 }

C#

1 public void imge() 2 { 3 ///画像のファイル名のリスト 4 List<Item> imagelist = new List<Item>(){ 5 new Item {id = 1, Name ="りんご", Image = "apple.jpg"}, 6 new Item {id = 2, Name ="ペン", Image = "seal.jpg" }, 7 new Item {id = 3, Name = "ぬいぐるみ", Image = "no_image.jpg"} 8 }; 9 10 //商品画像をセット 11 for (int i = 0; i < imagelist.Count; i++) 12 { 13 //商品情報のトップの位置 14 var locationY = 70; 15 //商品情報の配置の間隔 16 var location = i * 140; 17 18 var name = imagelist[i].Name; 19 20 //画像ファイルを読み込んで、Imageオブジェクトとして取得する 21 Image img = Image.FromFile(@"C:\test\" + imagelist[i].Image); 22      23 PictureBox pictureBox = new PictureBox() 24 { 25 Name = name, 26 Image = img, 27 Size = new Size(100, 100), 28 SizeMode = PictureBoxSizeMode.Zoom, 29 }; 30 pictureBox.Location = new Point(40, locationY + location); 31 Controls.Add(pictureBox); 32 }

実現したいこと

・必ず、

C#

1 ///画像のファイル名のリスト 2 List<Item> imagelist = new List<Item>(){ 3 new Item {id = 1, Name ="りんご", Image = "apple.jpg"}, 4 new Item {id = 2, Name ="ぬいぐるみ", Image = "seal.jpg" }, 5 new Item {id = 3, Name = "ペン", Image = "no_image.jpg"} 6 }; 7 8プロジェクト名のフォルダーだけを送るだけで実行する。

のImage = "apple.jpg"の部分を使って画面表示を行うことである。

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

Image img = Image.FromFile(@"C:\test\" + imagelist[i].Image);

で例外が発生した。
エラーのメッセージの内容は
System.IO.FileNotFoundException
HResult=0x80070002
Message=C:\test\apple.jpg
Source=System.Drawing.Common
である。

調べたこと・実行したこと

1.サイトでアプリケーションのリソースとして画像を埋め込んで使用する方法があると書いていたが、
その方法がわからない。

2.原因が完全パスのやり方によって実行できないと考えたので、
画像ファイルのパスを相対パスで指定するように書く方法

「プロジェクト」のを右クリックして、
「新しいフォルダー」を追加し、名前はimageとする。

エクスプローラーから画像をドラッグ&ドロップで追加
イメージ説明
画像ファイルのパスは相対パスで指定するように書く方法で行った。

C#

1//商品画像をセット 2 for (int i = 0; i < imagelist.Count; i++) 3 { 4 //商品情報のトップの位置 5 var locationY = 70; 6 //商品情報の配置の間隔 7 var location = i * 140; 8 9 var name = imagelist[i].Name; 10 11 //画像ファイルを読み込んで、Imageオブジェクトとして取得する 12 Image img = Image.FromFile(@".\image\" + imagelist[i].Image);//相対パスで指定するようにコードを書いた 13 14 PictureBox pictureBox = new PictureBox() 15 { 16 Name = name, 17 Image = img, 18 Size = new Size(100, 100), 19 SizeMode = PictureBoxSizeMode.Zoom, 20 }; 21 pictureBox.Location = new Point(40, locationY + location); 22 Controls.Add(pictureBox); 23 }

しかし、
System.IO.FileNotFoundException
HResult=0x80070002
Message=C:\Users\------\source\Visal\FreeTraining\FreeTraining\bin\Debug\net6.0-windows\image\apple.jpg

とエラーが発生してしまった。

その後もサイトで調べたことは2の書き方も1のアプリケーションのリソースについて関係がある書き方をしていた。

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

SurferOnWww

2022/11/14 22:09 編集

> 自分のパソコンでは動くけど、他人のパソコンで実行すると動かなくなったので、 動く・動かないというのはどういう状況を言っているのですか? そこを詳しく書いてください。 エラーが出てるならエラーメッセージを質問欄にコピペしてください。エラーメッセージは非常に重要な情報で、それだけで原因と対策が分かることがあるのですよ。
samakimi

2022/11/15 11:26

動く・動かないというのはどういう状況については、 SurferOnWwwさんが書いていた ・他人のパソコン」に画像ファイルがないというような問題 ・画像ファイルは「他人」にも配布して「他人のパソコン」のどこかのフォルダに配置してもらったが、アプリで指定するファイルパスと、「他人」が画像ファイルを配置したファイルパスが違っていて、結果 System.IO.FileNotFoundException がスローされたのだろうと想像してレスします。 という解釈であっています。
SurferOnWww

2022/11/17 22:23

あなたの求めに応じて案 2 の説明は回答欄に追記しました。それで答えになっているはず。いつまでも引っ張らないでクローズしてください。

回答2

0

ベストアンサー

質問に対する返事がないのでいろいろ不明ですが・・・

フォルダーのパスで読み込む画像を指定すると、自分のパソコンでは動くけど、他人のパソコンで実行すると動かなくなったので、何か良い方法はありませんか?

たぶん、「他人のパソコン」に画像ファイルがないというようなプリミティブな問題ではなく、画像ファイルは「他人」にも配布して「他人のパソコン」のどこかのフォルダに配置してもらったが、アプリで指定するファイルパスと、「他人」が画像ファイルを配置したファイルパスが違っていて、結果 System.IO.FileNotFoundException がスローされたのだろうと想像してレスします。

【案1】

画像ファイルはそのアプリの exe のあるフォルダに配置してもらい、

イメージ説明

Application.ExecutablePath プロパティで .exe ファイルのパスを取得し、それから画像ファイルへのパスを組み立てる。

イメージ説明

【案2】

画像はリソースファイルに格納してそこから取得する。

イメージ説明

【案3】

前の質問者さんのスレッドによるとデータは SQL Server より取得するとのことなので、画像のバイト列データ(画像の名前ではなくバイト列そのもの)を SQL Server に保存しておき、アプリではそれから取得する。


【追記】

私は特に案3か案2のどちらかの方法について知りたいですが、案3について詳しく説明をお願いします。
申し訳ないお願いと思いますが、もし、時間など可能であれば案2について説明もお願いしたいです。

【案2】のやり方のみ以下に説明します。【案3】はもともとのこのスレッドの話「相対パスみたいな画像ファイルを表示する方法」とは違うことなので、その話がしたいのであれば新たに別スレッドを立てて質問してください。

まず、ソリューションエクスプローラーで Form1.resx を右クリックして開き、[イメージ]を選んでそのウィンドウに画像を配置してください。エクスプローラーからコピペできます。

成功するとプロジェクトルート直下に Resources というフォルダができ、その中に画像ファイルがコピーされます。下の画像を見てください。

イメージ説明

上の画像は ComponentResourceManager クラスを使って以下のコードで取得できます。

C#

1var resources = new ComponentResourceManager(typeof(Form1)); 2Image? image = resources.GetObject("sample1") as Image; 3if (image != null) 4{ 5 pictureBox1.Image = image; 6}

【案3】は新たに別スレッドを立てて質問してくださいと書きましたが、その前に、そもそも Windows Forms アプリで SQL Server を使うのが適切かを考えてください。

「他人のパソコン」にも SQL Server をインストールしてもらうなんてことは考えられないのでは? 複数のユーザーで SQL Server を共有できる環境を構築することも現実的ではないのでは?

そこはとりあえず置いといて話がしたいということでも、勉強して自力である程度コードが書けるようになってから、どうしても自力では解決できない点を質問するようにしてください。

投稿2022/11/15 02:56

編集2022/11/17 07:23
SurferOnWww

総合スコア17434

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

samakimi

2022/11/15 11:40

様々な回答ありがとうございます 【案1】のApplication.ExecutablePath プロパティで .exe ファイルのパスを取得し、それから画像ファイルへのパスのコードについては理解はできましたが 申し訳ございませんが 【案1】の画像ファイルはそのアプリの exe のあるフォルダに配置の仕方 や 【案2】の画像がリソースファイルに格納してそこから取得する方法が わからないです。 その2つの部分について詳しく説明をお願いします。 【案3】についてはどのような操作を行うことべきかもわかりません。 可能であれば、その作業に仕方を教えてください。
SurferOnWww

2022/11/15 23:59

全案詳しく説明するのは手間がかかりすぎでとってもやってられません。どれか一案を決めてください。
samakimi

2022/11/16 11:27 編集

私は特に案3か案2のどちらかの方法について知りたいですが、 案3について詳しく説明をお願いします。 申し訳ないお願いと思いますが、 もし、時間など可能であれば案2について説明もお願いしたいです。
SurferOnWww

2022/11/16 22:05 編集

現状から見るに、私のお勧めは案1です。なぜ案2, 3 が案1よりいいと思うのですか? そこが説明できない限り、誤った選択を疑わざるを得ないですけど。 案3を質問者さんに説明するのは、今までのやり取りから想像する質問者さんの知識レベルでは難しいと思います。話が通じる程度まで自分で勉強してから出直すことをお勧めします。そもそも、Windows Forms アプリで SQL Server を使うのが適切かから考えた方が良いと思います。
samakimi

2022/11/17 13:02 編集

案2について、Resources というフォルダができ、その中に画像ファイルが格納することができました。 そこから取得するコード Image img = Image.FromFile(@".\Resources\" + imagelist[i].Image); で指定したファイルを取得するコードを書きました。 System.IO.FileNotFoundException HResult=0x80070002 Message=C:\Users\------\source\Visal\FreeTraining\FreeTraining\bin\Debug\net6.0-windows\Resources\apple.jpg とエラーが発生しました。 格納した後に画像ファイルを取得するコードの書き方がわかりません。 その説明をお願いしたいです。
samakimi

2022/11/17 12:52

また、案1の方が案2よりおすすめな理由について、内容をご確認しましたが、 注意点が毎回新しい Bitmap オブジェクトが生成されることが注意であることで解釈でよいでしょうか? 確認をしてもなぜリソースから画像を取得するたび毎回新しいBitmapオブジェクトが生成されることが注意であるのかわかりません。
SurferOnWww

2022/11/17 13:22 編集

> そこから取得するコード > Image img = Image.FromFile(@".\Resources\" + imagelist[i].Image); > で指定したファイルを取得するコードを書きました。 【追記】を見てますか? 【追記】のどこにそんなことをするって書いてありますか?
SurferOnWww

2022/11/18 01:49

> また、案1の方が案2よりおすすめな理由について、内容をご確認しましたが、 > 注意点が毎回新しい Bitmap オブジェクトが生成されることが注意であることで解釈でよいでしょうか? それは理由の一つで、そういうことをすると予期せず余計なオブジェクトが生成されるので、扱いに注意すべきということです。 そういうことより、案1の方がお勧めなのは、あなたにとってより容易にやりたいことを実現できるであろうと思うからです。
samakimi

2022/11/18 12:49

案1についてのやり方については Resources というフォルダの中にある画像ファイルのプロパティに「出力ディレクトリにコピー」という設定項目があり、 その中で「新しい場合はコピーする」を指定して、ソリューションのリビルドをすると、 exe のあるフォルダと同じフォルダーにResources フォルダーができ、 そこに画像ファイルがありました。 その方法でできましたが、やり方が大丈夫ですか?
SurferOnWww

2022/11/18 13:12

話が通じないですね。 だったら最初から質問の画像にある image フォルダの jpg ファイルを「新しい場合はコピーする」と設定しておけばいいでしょう。それが案1です。

0

相対パス、ってのは、カレントディレクトリを基準としたパスの記述となります
そのカレントディレクトリ、ってのは、

  1. プログラムが存在する場所
  2. プログラムを実行した場所
  3. ショートカットの作業フォルダ

などなど、そのプログラムの実行方法により変わってきます
ってことで、まずはそのプログラムで、カレントフォルダを表示させるようにしてみましょう
それで、どこにそれが来るのか、を確認してみましょう。
はなしはそれからになります

投稿2022/11/14 13:39

y_waiwai

総合スコア86072

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

2022/11/14 14:03

こちらの回答が他のユーザーから「攻撃的な表現などを含む不快な回答」という指摘を受けました。

2022/11/15 11:42

こちらの回答が複数のユーザーから「質問に対する回答となっていない投稿」という指摘を受けました。

2022/11/14 22:07

こちらの回答が他のユーザーから「説明が不足している回答」という指摘を受けました。

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。