bash変数に画像ファイルを保存する方法は?


14

次のコマンドを使用した後、

pngString="$(cat example.png)"    
echo -n "$pngString" > tmp.png

tmp.pngをPNGファイルとして開くことができません。$pngString画像ファイルの保存に使用すると、一部の情報が失われる場合があります。

質問は次のとおりです。bashスクリプトの変数を使用して完全な画像情報を保存するにはどうすればよいですか。


catコマンドは正常に動作します(画像データを変数に保存するため)。二重引用符を削除するだけです。問題は、変数に保存した後、このデータで何をしたいですか?
coffeMug

5
catそしてecho、そのすべてが中心的なテキストユーティリティです。バイナリファイルでそれらを無意識に緩めると、予測できない結果が生じます。そのようなものbase64が発明されたのはそのためです。
シャドゥール

なぜ変数として使用したいのですか?シェル変数は通常、大量のバイナリデータではなく、少量のテキストを格納することを目的としています。通常のシェルは、zshを除き、変数内のバイナリデータ(nullバイトでチョークする)に対処できません。
ジル「SO-悪であるのをやめる」

どうしてcat example.png > tmp.pngまだまだ良いのcp example.png tmp.pngですか?
ワイルドカード

@Shadur catは、実際にはテキストユーティリティではありません。コマンドの置換(末尾の改行を削除)、変数の割り当て(nullバイトを含めることはできません)、およびechoコマンド(バックスラッシュシーケンスを解釈する可能性があります)は、バイナリではなくマングルcatです。しかし、私はあなたの全体的なポイントに同意します。
ワイルドカード

回答:


20

あなたはその通りであり、echo会社はバイナリをうまく処理していないようです。null文字がストリームを早すぎる段階で中断させているのではないかと思います。

ASCIIベースの形式で画像情報を変換できます。たとえば、これはbase64次のとおりです。

$ pic=`base64 pic.jpeg`
$ echo $pic | base64 --decode > pic2.jpeg
$ diff pic*
$ echo $?
0

3
私のbashのシステムでは、私は、base64に空白を含めることができるので、おそらく、引用符で変数を囲むために持っていた: echo "$pic" | base64 --decode > pic2.jpeg
OldTimer

1

問題は、ヌルバイトは引数の終端として内部的に使用されるため、コマンドライン引数を介して渡すことができないことです。他のすべてのバイトは問題ないようです。したがって、使用するよりもスペース効率が高い(通常)代替方法base64は、nullバイトをエスケープしてprintfから、データを元の形式に変換することです。

pngString="$(sed 's/\\/\\\\/g;s/%/%%/g;s/\x00/\\x00/g' <example.png)"
printf "$pngString" >tmp.png

文字がに特別な彼らはあまりにもエスケープする必要がありますので。\%printf

また、入力データが改行で終わる場合、コマンド置換によって削除されることに注意してください。有効なPNGの最後のバイトは0x82(空のIENDチャンクのCRC合計の最下位バイト)である必要があるため、PNGの場合は特に問題になりません。


1
あなたも、より多くのバックスラッシュ、使用したい場合: sed s/\\\\/\\\\\\\\/g\;s/%/%%/g\;s/\\x00/\\\\x00/g
カレル・VLK
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.