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

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

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

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

ImageMagick

ImageMagickとは、画像の表示や操作を行うオープンソースのソフトウェアです。プログラムはCで書かれており、GIFやJPEG、PDFなど画像ファイルフォーマット100種類以上に対応しています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

1425閲覧

アップロードする画像のexif情報を削除するには

hatano

総合スコア7

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

ImageMagick

ImageMagickとは、画像の表示や操作を行うオープンソースのソフトウェアです。プログラムはCで書かれており、GIFやJPEG、PDFなど画像ファイルフォーマット100種類以上に対応しています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2018/04/17 06:12

編集2018/04/17 07:08

perlで写真をアップロードするフォームがあります。
写真をフォームからアップロードするとサーバーの写真用の保存フォルダに保存され、その写真をウェブ上で見れるようにしています。
今は写真をアップロードすると写真のexif情報もそのまま保存されます。
これをアップロードする時に写真からexif情報を削除してアップロードしたいと考えています。

調べてみるとImage::Magickのstripオプョンを使うことでexif情報が削除できるとのことで、
アップロードする写真の保存処理の部分にImage::Magickのstripオプョンを組み込むのではないかと思うのですが、
どのようにすればよいのかわかりません。

以下は、HTML上のアップロードするフォームとperlの写真の保存処理のコードです。
利用しているサーバー(ロリポップ)ではImage::Magickは利用可(パスは /usr/bin/convert)となっています。

#HTML <input type="file" name="●●●" />
#PERL sub UpFile { $macbin=0; foreach (@in) { if ($_ =~ /(.*)Content-type:(.*)/i) { $tail=$2; } if ($_ =~ /(.*)filename=(.*)/i) { $fname=$2; } if ($_ =~ /application/x-macbinary/i) { $macbin=1; } } $tail =~ s/\r//g; $tail =~ s/\n//g; $fname =~ tr/\"\x0D\x0A//d; $flag=0; if ($tail =~ /image/gif/i && $gif) { $tail=".gif"; $flag=1; } if ($tail =~ /image/jpeg/i && $jpeg) { $tail=".jpg"; $flag=1; } if ($tail =~ /image/x-png/i && $png) { $tail=".png"; $flag=1; } if (!$flag) { if ($fname =~ /.gif$/i && $gif) { $tail=".gif"; $flag=1; } if (($fname =~ /.jpe?g$/i && $jpeg)) { $tail=".jpg"; $flag=1; } if ($fname =~ /.png$/i && $png) { $tail=".png"; $flag=1; } } foreach $confirm_type (@confirm_type) { if ( $fname =~ /.$confirm_type$/i ) { $tail=".$confirm_type"; $flag=2; $org_width="file"; last; } } if (!$flag) { return; } elsif (!$flag) { &error("アップロードできないファイル形式です","lock"); } $upfile = $in{'upfile'}; if ($macbin) { $length = substr($upfile,83,4); $length = unpack("%N",$length); $upfile = substr($upfile,128,$length); } $ImgFile = "$ImgUrl$no$tail"; open(OUT,"> $ImgFile") || &error("画像のアップロードに失敗しました","lock"); binmode(OUT); binmode(STDOUT); print OUT $upfile; close(OUT); chmod (0666,$ImgFile); if ($tail eq ".jpg") { ($W, $H) = &JpegSize($ImgFile); } elsif ($tail eq ".gif") { ($W, $H) = &GifSize($ImgFile); } elsif ($tail eq ".png") { ($W, $H) = &PngSize($ImgFile); } elsif ( $flag eq "2" ) { $W = $down_ix; $H = $down_iy; } if ($W > $MaxW || $H > $MaxH) { $orw = $W; $orh = $H; $W2 = $MaxW / $W; $H2 = $MaxH / $H; if ($W2 < $H2) { $key = $W2; } else { $key = $H2; } $W = int ($W * $key) || 1; $H = int ($H * $key) || 1; } } sub JpegSize { local($jpeg) = @_; local($t, $m, $c, $l, $W, $H); open(JPEG, "$jpeg") || return (0,0); binmode JPEG; read(JPEG, $t, 2); while (1) { read(JPEG, $t, 4); ($m, $c, $l) = unpack("a a n", $t); if ($m ne "\xFF") { $W = $H = 0; last; } elsif ((ord($c) >= 0xC0) && (ord($c) <= 0xC3)) { read(JPEG, $t, 5); ($H, $W) = unpack("xnn", $t); last; } else { read(JPEG, $t, ($l - 2)); } } close(JPEG); return ($W, $H); }

以下は参考サイトなどを見ながら自分でやってみたものですが、アップされた写真のexif情報は削除されませんでした。

sub UpFile { $macbin=0; foreach (@in) { if ($_ =~ /(.*)Content-type:(.*)/i) { $tail=$2; } if ($_ =~ /(.*)filename=(.*)/i) { $fname=$2; } if ($_ =~ /application/x-macbinary/i) { $macbin=1; } } $tail =~ s/\r//g; $tail =~ s/\n//g; $fname =~ tr/\"\x0D\x0A//d; $flag=0; if ($tail =~ /image/gif/i && $gif) { $tail=".gif"; $flag=1; } if ($tail =~ /image/jpeg/i && $jpeg) { $tail=".jpg"; $flag=1; } if ($tail =~ /image/x-png/i && $png) { $tail=".png"; $flag=1; } if (!$flag) { if ($fname =~ /.gif$/i && $gif) { $tail=".gif"; $flag=1; } if (($fname =~ /.jpe?g$/i && $jpeg)) { $tail=".jpg"; $flag=1; } if ($fname =~ /.png$/i && $png) { $tail=".png"; $flag=1; } } foreach $confirm_type (@confirm_type) { if ( $fname =~ /.$confirm_type$/i ) { $tail=".$confirm_type"; $flag=2; $org_width="file"; last; } } if (!$flag) { return; } elsif (!$flag) { &error("アップロードできないファイル形式です","lock"); } $upfile = $in{'upfile'}; if ($macbin) { $length = substr($upfile,83,4); $length = unpack("%N",$length); $upfile = substr($upfile,128,$length); } $ImgFile = "$ImgUrl$no$tail"; ####以下を追記してみましたがアップされた写真のexif情報は削除されませんでした#### my $im = new Image::Magick; $im -> Read( $ImgFile ); $im -> Strip; $im -> Write( $ImgFile ); ####//追記#### open(OUT,"> $ImgFile") || &error("画像のアップロードに失敗しました","lock"); binmode(OUT); binmode(STDOUT); print OUT $upfile; close(OUT); chmod (0666,$ImgFile); if ($tail eq ".jpg") { ($W, $H) = &JpegSize($ImgFile); } elsif ($tail eq ".gif") { ($W, $H) = &GifSize($ImgFile); } elsif ($tail eq ".png") { ($W, $H) = &PngSize($ImgFile); } elsif ( $flag eq "2" ) { $W = $down_ix; $H = $down_iy; } if ($W > $MaxW || $H > $MaxH) { $orw = $W; $orh = $H; $W2 = $MaxW / $W; $H2 = $MaxH / $H; if ($W2 < $H2) { $key = $W2; } else { $key = $H2; } $W = int ($W * $key) || 1; $H = int ($H * $key) || 1; } }

Image::Magick以外の方法でも構いませんので、アップロードする画像のexif情報を削除する方法がありましたらばアドバイスお願いいたします。

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

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

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

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

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

m.ts10806

2018/04/17 06:18

「うまく動作しない」「うまくいかない」では何が起きているか伝わりません。「○○のようになるはずなのに××となってしまう」のような形で「ゴール」と「現象」を明確にしてください。https://teratail.com/help/question-tips#questionTips3-4-1
hatano

2018/04/17 07:01

わかりにくい文面で申し訳ありません。質問文を訂正させていただきましたので、よろしければご確認いただければ幸いです。
m.ts10806

2018/04/17 07:08

そもそも「画像のアップロード処理」自体はできているという認識で良いですか?どこまでできていて、どこからできていないというところも教えてください。
m.ts10806

2018/04/17 07:09

何度も確認すみません。exif情報の確認はどのように行っているのでしょうか?
hatano

2018/04/17 07:10

ありがとうございます。「画像のアップロード処理」自体は問題なくできています。この状態から写真のexif情報を削除して保存させたいと考えています。
hatano

2018/04/17 07:13

exif情報の確認は、サーバーの写真用保存フォルダに保存された写真をフォトビューアーで開きプロパティを見て確認しています。また、ウェブ上で右クリックでアップされた写真をダウンロードしてプロパティを確認するとexif情報が載っています。
m.ts10806

2018/04/17 07:15

念のため参考にしたサイトのURLを追記いただけますか?
CHERRY

2018/04/17 07:24

試されたソースコードで、$im->Write( $ImgFile ); の部分で、「別名」で新しいファイルとして保存したら、新しいファイルに exif 情報は残っていますか?
hatano

2018/04/17 07:33 編集

>CHERRYさん ありがとうございます。申し訳ありませんが、「「別名」で新しいファイルとして保存したら」というのはどういうことでしょうか?
CHERRY

2018/04/17 07:36 編集

現在、Read( $ImgFile ) して Write( $ImgFile ) なので、上書きしていると思いますが、保存に失敗しても元のファイルが残るので、 確認した際に「Exif が消せなかった」のか「Exifが消せたが保存に失敗した」だけなのか判断がつかないので、「保存するときに新しいファイルにして原因の切り分けしてください」という依頼です。
hatano

2018/04/17 07:37

>CHERRYさん $im->Write( $ImgFile ); → $im->Write( $ImgExifFile ); としてみましたがアップされた写真のexif情報は削除されていませんでした。
CHERRY

2018/04/17 07:46 編集

質問に記載されたコードでは、代入されている部分がないのですが、 $ImgUrl や $no には、正しい値が入っているんですよね?  グローバル変数ですか?
hatano

2018/04/17 08:19

>CHERRYさん $ImgUrlや$noには正しい値が入っています
hatano

2018/04/17 08:19

はい、グローバル変数です
CHERRY

2018/04/17 08:30 編集

chmod (0666,$ImgFile); の次の行に system( "/usr/bin/convert -strip ${ImgFile} ${ImgFile}_new.jpg" ); を追加して、コマンドラインの convert コマンドで変換して出力される、画像ファイル名の後ろに new.jpg が付いたファイルの exif は、どうなるでしょう?
hatano

2018/04/18 01:31 編集

>CHERRYさん 昨日は所用によりご返信ができなくなり申し訳ありませんでした。system( "/usr/bin/convert -strip ${ImgFile} ${ImgFile}_new.jpg" ); を追加したところアップロードされたファイル名の後ろに new.jpg が付いた写真ではexif情報が削除されていました。その後、ファイル名を変更させないために system( "/usr/bin/convert -strip ${ImgFile} ${ImgFile}" ); として再度アップロードを試したところファイル名を変えずにアップロードした写真からexif情報を削除することができていました。ただ、この私のやり方が正しいものなのか判断がつかないのですが、希望する動きはしてくれるようになりました。本当にありがとうございました。ベストアンサーをつけさせていただきたいのですが、何か回答文をお書きいただければ幸いです。
guest

回答1

0

ベストアンサー

コメント欄に記載した「convert」コマンドを呼び出す方法で、成功したということですので、コメント欄から補足しつつ転記しておきます。


質問に記載されたプログラムで、ファイル保存後に chmod (0666,$ImgFile); している次の行に

system( "/usr/bin/convert -strip ${ImgFile} ${ImgFile}_new.jpg" );

を追加して、外部コマンドとして convert コマンドを実行して Exif を削除するのはどうでしょうか?

返還後のファイル 画像ファイル名new.jpg が、保存されていると思いますので、exif が削除されているか確認してください。


(追記)

パソコンから見て気がつきましたが、質問に書かれた ImageMagick プログラムは ImageMagick の処理を入れている位置がおかしいですね。(スマホからみていたので、見落としていました。)

質問に書かれているプログラムでは、ImageMagick の Write( $ImgFile ); で保存した後に open(OUT,"> $ImgFile") して、アップロードした画像をそのまま保存しているので、保存した画像ファイルを確認しても Exif は削除されていなかったのだと思われます。

以下、現在テスト環境がないので、テストできていないのですが...

質問のプログラムの

$ImgFile = "$ImgUrl$no$tail";

 ####以下を追記してみましたがアップされた写真のexif情報は削除されませんでした####
my $im = new Image::Magick;
$im -> Read( $ImgFile );
$im -> Strip;
$im -> Write( $ImgFile );
####//追記####
open(OUT,"> $ImgFile") || &error("画像のアップロードに失敗しました","lock");
binmode(OUT);
binmode(STDOUT);
print OUT $upfile;
close(OUT);
chmod (0666,$ImgFile);

を 下記のように変更したら Image::Magick モジュールで、Exif を削除できないでしょうか?

$ImgFile = "$ImgUrl$no$tail"; open(OUT,"> $ImgFile") || &error("画像のアップロードに失敗しました","lock"); binmode(OUT); binmode(STDOUT); print OUT $upfile; close(OUT); chmod (0666,$ImgFile); my $im = new Image::Magick; $im->Read( $ImgFile ); $im->Strip; $im->Write( $ImgFile );

さらに、$upfile に アップロードした画像データが入っているのであれば、画像を保持している変数($upfile)から読み込むようにして、Image::Magick で処理後に保存する方法が良さそうです。
( Perl-Magick : Working with Blobs参照 )

$ImgFile = "$ImgUrl$no$tail"; my $im = new Image::Magick(); $im->BlobToImage($upfile); $im->Strip; $im->Write( $ImgFile ); chmod (0666,$ImgFile);

投稿2018/04/18 02:39

編集2018/04/18 03:24
CHERRY

総合スコア25171

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

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

hatano

2018/04/18 04:43

最後までご丁寧にご回答いただき本当にありがとうございます。 >質問に書かれているプログラムでは、・・・ ImageMagickの処理を入れている位置がおかしかったということで、早速教えていただいた内容に変更しテストをしてみた結果、アップロードされた画像からはexif情報がちゃんと削除されており、希望通りの動作をしてくれました! >さらに、$upfile に アップロードした画像データが入っているのであれば、画像を保持している変数($upfile)から読み込むようにして・・・ $upfileにはアップロードした画像が入っていますので、こちらの後述の方法を試した見たところ、問題なく希望通りの動きをしてくれました。 BlobToImage()の使い方の知識が乏しかったものでとても勉強になりました。 本当に助かりました。 ありがとうございました。 追伸 後述のコードを試したテストでは、教えていただいたコードそのままに$ImgFile = "$ImgUrl$no$tail"; から下の open(OUT,"> $ImgFile") || &error("画像のアップロードに失敗しました","lock"); binmode(OUT); binmode(STDOUT); print OUT $upfile; close(OUT); これらを削除して実行しました。 そこで1点疑問なのですが、 open(OUT,"> $ImgFile") || &error("画像のアップロードに失敗しました","lock"); のコードをなくした場合、エラー時に表示されるコメント(画像のアップロードに失敗しました)はどのようになるのでしょうか? よろしければご教授いただけませんでしょうか。
CHERRY

2018/04/18 05:12 編集

問題なく動いたようで何よりです。 Perl のスクリプトなんて、随分久しぶりなので、かなり忘れてますね... (苦笑) ワンライナーは、ときどき書いているのですけどね... 現状だとエラーメッセージは出していないので、おそらくシステムのエラー処理になってしましますね。 ` $result = $im->Write( $ImgFile ); ` のように返り値を受け取るようにすると $result に実行結果のステータスコードが入ります。 成功すると 0 です。失敗するとエラーが入りますので、$result を利用して、メッセージを表示することになると思います。 たとえば、 $result = $im->Write( $ImgFile ); if( $result ) { warn "$result"; } else { print "ファイル保存成功"; } のような感じでしょうか。( 質問に記載されたプログラムでは、&error でメッセージを出しているような感じですが、処理内容がわからなかったので、perl標準のメッセージ表示にしています。 ) Image::Magick のエラーメッセージの一覧は、 https://www.imagemagick.org/script/exception.php を参照してください。 もしかすると コードからメッセージに置き換える必要があるかもしれません。
hatano

2018/04/18 05:14

ご回答ありがとうございます。 >$result = $im->Write( $ImgFile ); ` のように返り値を受け取るようにすると・・・ >成功すると 0 です。失敗するとエラーが入りますので・・・ とてもわかりやすくて助かります、本当に感謝です。 参考URLを確認し、あとは自分で勉強しながら調べてやってみようと思います。 今回は最後までお付き合いいただきありがとうございました。 とても助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問