web-dev-qa-db-ja.com

メモ帳でJPG画像を開き、すべての「テキスト」を新しいメモ帳ファイルに貼り付け、.JPGに変更して開くことができなくなりました。どうして?

この現象は私に尋ねるべき質問を残しています。

これが詳細な実験です。私のOSはWindows 7 x64 SP1です。

  • 拡張子を変更することで、画像(JPG)ファイルをTXTに変更しました(または、メモ帳でJPGを開くことを選択することもできます、同じこと)。

下のスクリーンショットの「作成者:dg-jpeg v1.0 ...」のように、これは奇妙に見える一連のテキストで、実際には意味があります(ごくまれです)。

Sample JPG text

  • 折り返しを無効にし、Ctrl + Aを押してすべてのテキストを選択しました(見逃していないことを確認するため)。
  • コピーしたテキストを別の空白のTXTファイルに貼り付けてJPGとして保存し、新しいファイルサイズと元のJPGを比較しました。それらすべて(元のJPG、変換されたTXTファイル、および新しく作成されたTXTファイル)は、完全に同じサイズです。バイトに。

開こうとすると、Windowsは「ファイルが破損しているか、壊れているか、大きすぎるため、この画像を開けません」と表示します。

メモ帳でJPGを開き、覚えやすい場所からONE既知の文字を切り取ります(2行目の最初の文字のように)。 )ファイルを保存します。視聴者はもちろん同じメッセージを表示します。それからそれを再び開いて、文字をEXACTの位置に貼り付けました(メモ帳はウィンドウの位置、折り返し、フォントサイズなどの終了状態を記憶しています。この権利)

それでも同じエラーです。あなたはアイデアを得るためにこれを試みることができます、さもなければメモ帳が老さびた人のように振る舞う小さい絵を選ぶのを忘れないでください。

この現象の原因は何でしょうか。

82

ファイルを開くために使用されるエンコーディングによっては、動作が異なる場合があります。私のWindows 7のメモ帳では、ANSI、UTF-8、Unicode、またはUnicodeビッグエンディアンでファイルを開くことができます。

私はgimpで作成されたANSIエンコーディングで画像ファイルを開いて保存する小さな2 x 2ピクセルのJPEG画像でこの問題をテストしました。元の画像と保存された画像の両方を16進エディタで開くと、00シーケンス(2桁の16進数、 NUL制御文字 )がすべて20に変換されました。 (スペース文字).

20をすべて16進数エディタで置き換えると、画像フォーマットが復元されます。

私はそれを少しグーグルしました、そしてなぜそれがそうするのかを説明する参考文献を見つけませんでした。警告を表示する投稿への参照のみ(Googleキャッシュリンク、ページは表示されません)。

ファイルをUTF-8として保存または開くと、NUL文字はスペースに変換されますが、シングルバイト文字からUTF-8マルチバイトシーケンスへの変換により、ファイルサイズも大きくなります。

ファイルをUnicodeで保存/開くと、NUL文字をスペースに変換するだけでなく、ファイルの先頭に1バイトが追加されるようです。 BOM .

81
mangper

失敗する理由

Windows APIのテキストボックスではnullで終わる(ASCII code 32) _ asciiz _ (文字配列、ポインタ)しか使用できないため、メモ帳では _ nul _ (ASCII code 0)のような文字にスペースchar *文字を作成できます。 最初のNULで切り捨てられます。

これは、 Windows API の大部分が _ c _ languageで記述され、 ヌル終端文字列 が一般的な機能の1つであるためです。現代のWindowsとUnicodeが同じNULL終端文字列と見なされる場合でも発生します。だからメモ帳はあなたが完全なファイルを見ることができるように単にそれらをスペースで置き換える。

だからあなたがファイルを保存するとそれは破損しています。

ウィキペディア - ヌル文字で終わる文字列


さらなる調査方法

のような比較(コマーシャル、トライアル) のような比較子を使って文字置換効果を確認することができます。 他のバイナリ比較ツール もご覧ください。

hex comparison

:(20)16 =(32)10年


メモ帳の理由が大きなファイルでゆっくりと機能する


Notepad.exe(XP 32 bit)を調べます。

(私はまだC++で書かれているか、少なくとも同等の linker を使っていると私は思っています)

notepad

私は PEiD ツールを使っています(これはPE +/64 exesの導入で開発を止めました)

PEiDは Universal Extractor のbinフォルダにバンドルされています。

メモ帳を取り出した。明らかにWindows XP ISOからex_ファイル。やってみよう。 7zを使ったcabファイルの抽出です。

警告!ウイルススキャナーはUniversal Extractor/PEiDをハッキングツールやウイルスとして検出する可能性があります。信頼しないでダウンロードしないでください。


Windows APIに関する詳細情報

クレジット:Jason C

テキストボックスだけではありません。 WM_SETTEXT は通常、文字列の長さを指定するためのパラメータを提供しません。また、文字列は常にnullで終了すると見なされます。文字列の長さを指定したカスタムメッセージを使用してカスタムテキストボックスをいつでも作成できますが、メモ帳やその他のほとんどのプログラムでは合理的に指定されていません。関数 SetWindowText も長さパラメータを提供しません。

メモ帳は、すべての特殊/拡張文字をそのままには保持しません。私はすぐにはこの振る舞いについてのリファレンスを持っていませんが、これは例えばメモ帳がCRLFとnull(0x00)に変換するUNIXスタイルの行末LFの場合に当てはまることがわかりました。無視します。 JPGなどのバイナリファイルでは、メモ帳に保存されていない文字がランダムに出現する可能性があります。 HEX対応のエディタで実験を試してください。そうすればうまくいきます。良い参考文献が見つかり、HEXエディタをテストしたら回答を更新します。

更新:私はいくつかの有名なプログラマー編集者を試しましたが、そのうちの1人だけがすぐにうまくいきました、 MaëlHörzによるHxD 。私はこれまでHxDを使ったことはありませんでしたが、このStack記事への回答のおかげでそれを発見しました。 Notepad ++用の16進ビューア/エディタプラグイン

数分経っても動作しないその他のエディタは、Notepad ++、Notepad2、およびUltraEdit(v17.3、旧バージョン)です。これらのうちのいくつかは、最初の数バイトのコピー/ペースト、JPEG ファイルシグネチャマジックナンバー FF D8 FFに問題がありました。たぶん、彼らは私が現時点でいる時間よりも少し手間をかけて仕事をするでしょう。

28
JohnC

あなたはこれを一日のうちに書き戻すことでできるようになりました。これはWindows 3.1の標準プログラムでしたが、Windows 95に含まれていたかどうかは思い出せません。書き込みはそれが開くことができる任意のファイルのバイナリセーフ編集を可能にするでしょう(おそらく非常に限られたファイルサイズ)。メモ帳は間違いなくバイナリセーフではありません(テキストは変わりませんが、実際の非テキスト文字のバイト数(コントロールコードなど)は変わる可能性があります)。これがJPGの例が機能しない理由です。 Write(および非常に古いWindows)のコピーを入手して、もう一度試してください。

ウィキペディアの "Windows Write"記事 によると、Windows NT 3.5まではWriteが含まれていました。 Windows 95以降ではワードパッドに置き換えられました。 write.exeはまだWindowsディレクトリに存在していましたが、単にワードパッドを開くためのラッパーでした。

6
CJ Dennis

エンコードの問題ではなく、文字セットの問題でもあると思います。 JPG形式は基本的にバイトストリームです。したがって、NUL、ETX、STX、SOH、DLEなどの印刷不能文字を許可します。

Microsoftのメモ帳ではこれらの印刷できない文字を表示できません。ヌル文字用のスペースのようなある種のプレースホルダーを表示することがあります。メモ帳でファイルを開いても実際の内容は表示されませんが、選択されたエンコーディング(utf-8、utf-16など)でデコードされ、特定の文字セット(unicode、asciiなど)で表示されます。印刷可能な文字.

表示されているテキストをすべて選択してそのテキストをクリップボードにコピーするときは、プレースホルダを含む印刷可能文字だけをコピーします。したがって、ヌル文字を自動的にスペースに変換し、他の印刷不能文字を完全に無視します。

したがって、基本的には、この方法でコンテンツを失うだけです。代わりに16進エディタを使用すると、すべてのコンテンツが完全にコピーされます。


更新:Bhathiya Pererasの答えは正しい: https://superuser.com/a/782885/322784 テキストのコピー時に印刷不能文字が無視されないクリップボードに。

5
sbecker

JPEGファイルには、一部のフィールドを除いてテキスト以外のデータが含まれています。基本的に、0から255までの任意のバイト値、特に擬似乱数データを含むエンコードされた圧縮イメージを表す領域にあります。

しかしNotepadはデフォルトでデータをANSIテキストとして扱うので、元のデータを変更するさまざまなことを行います。

  • 特殊な/未定義の/禁止された文字をマッピングするバイトは、有効なANSIテキストにとって意味がないので置き換えます。

  • ヌル文字、行の終わり、およびファイルの終わりのシーケンスをWindows/DOSの規則に再エンコードします。

つまり、データを編集してテキストとして保存すると、jpegが変更され、最悪の場合は使用できなくなります。

2
Dice9