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

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

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

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

Visual Studio

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

Q&A

解決済

2回答

1714閲覧

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

samakimi

総合スコア3

C#

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

Visual Studio

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

0グッド

0クリップ

投稿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のアプリケーションのリソースについて関係がある書き方をしていた。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2022/11/14 22:09 編集

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

2022/11/15 11:26

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

退会済みユーザー

2022/11/17 22:23

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

回答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
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

samakimi

2022/11/15 11:40

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

退会済みユーザー

2022/11/15 23:59

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

2022/11/16 11:27 編集

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

退会済みユーザー

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オブジェクトが生成されることが注意であるのかわかりません。
退会済みユーザー

退会済みユーザー

2022/11/17 13:22 編集

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

退会済みユーザー

2022/11/18 01:49

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

2022/11/18 12:49

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

退会済みユーザー

2022/11/18 13:12

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

0

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

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

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

投稿2022/11/14 13:39

y_waiwai

総合スコア87747

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問