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

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

ただいまの
回答率

90.51%

  • HTML

    9013questions

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

  • Perl

    457questions

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

  • ImageMagick

    94questions

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

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 333

hatano

score 1

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情報を削除する方法がありましたらばアドバイスお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

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

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

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • hatano

    2018/04/17 17:19

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

    キャンセル

  • CHERRY

    2018/04/17 17:30 編集

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

    キャンセル

  • hatano

    2018/04/18 10:05 編集

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

    キャンセル

回答 1

checkベストアンサー

+2

コメント欄に記載した「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 13: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"); のコードをなくした場合、エラー時に表示されるコメント(画像のアップロードに失敗しました)はどのようになるのでしょうか?
    よろしければご教授いただけませんでしょうか。

    キャンセル

  • 2018/04/18 14:08 編集

    問題なく動いたようで何よりです。

    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 を参照してください。
    もしかすると コードからメッセージに置き換える必要があるかもしれません。

    キャンセル

  • 2018/04/18 14:14

    ご回答ありがとうございます。

    >$result = $im->Write( $ImgFile ); ` のように返り値を受け取るようにすると・・・
    >成功すると 0 です。失敗するとエラーが入りますので・・・
    とてもわかりやすくて助かります、本当に感謝です。

    参考URLを確認し、あとは自分で勉強しながら調べてやってみようと思います。
    今回は最後までお付き合いいただきありがとうございました。
    とても助かりました。

    キャンセル

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

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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

  • HTML

    9013questions

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

  • Perl

    457questions

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

  • ImageMagick

    94questions

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