10217


環境  
- Windows7  
- Python2.7  
- Sublime Text3

対象はヘッダーを含む16bitのImgファイル（X線測定で得た画像ファイル）です．  
ヘッダーの編集を自動化するために，テキストファイルとして読み込んで一部を書き換える，ということをしようとしています．

ファイルサイズが14Mbと比較的大きいため，コーディングしているときは，ヘッダー部だけをあらかじめ切り出し，拡張子をimgにしたファイルを使用していました．

そのときは下のように，ファイルをエディタで開いたときと同じような配列

[code]

    522d 4158 4953 2d43 5320 312e 302d 322e 3020 2020 476c 7963 696e 6520 2020 2020 2020 2020 2020 2020 7472 6967 6f6e 616c...
    
[/code]

が取り出せていたのですが，いざ元のimgファイルに対してプログラムを実行したところ，取り出せたのは

[code]

    R-AXIS-CS 1.0-2.0   Glycine             trigonal    @\xe19\xc1@\xe19\xc1@\xaff\xcfB\xb4\x00\x00B\xb4\x00\x00B\xf0\x00\x00P31\x00m       ...
    
[/code]

のように，エンコードが変わった（？）ものになってしまいました．

単にファイルをopen()してreadline()しただけなのですが．．．

[code]

    with open('sample.img', 'rb') as f:
        for i in range(60):
            data = []
            list1 = f.readline()
            data.append(list1)
    print data
    
[/code]

普通に16進数の配列として取り出すにはどうしたらよいでしょうか？  
そもそも，テキストとして開こうとしているのが間違いなのでしょうか?

文字コードなどに詳しくないので，何が起きてるかさっぱりわかりません．  
よろしくお願いします．


CC BY-SA 3.0
2015-05-15T05:43:20.057
10215
2015-05-15T07:50:20.550
9744
question
python テキストファイル
テキストファイル読み込みの際のエンコードが勝手に変わる？


質問のタイトルと実際にやっていることが食い違っている気がします。  
画像ファイルをテキストとして開く理由はなんでしょう？実装コードはバイナリで開いているようですが・・

[code]

    open('sample.img', 'rb')
    
[/code]

'rb' なので read binary です。テキストとして開いていません。バイナリとして開いています。

[code]

    list1 = f.readline()
    
[/code]

バイナリに「行」の概念はないので、この処理はどうなるかわかりません。

[code]

    with open('sample.img', 'rb') as f:
        data = f.read()
    
[/code]

で全データをバイナリとして読み込めると思います。  
先頭100byteだけ読み込みたければ、

[code]

    with open('sample.img', 'rb') as f:
        data = f.read(100)
    
[/code]

のようにすれば良いでしょう。


CC BY-SA 3.0
2015-05-15T06:21:59.303
10216
2015-05-15T06:21:59.303
806
10215
answer


元ファイルを SublimeText で開いたとき、このような画面で表示されたのではないでしょうか？

![画像の説明をここに入力](https://i.stack.imgur.com/j94XR.png)

このときSublimeTextは、そのファイルを **バイナリファイルとして**
、1バイトを2桁の16進数で表示しています。強引にテキストとして表示した結果が、あなたのプログラムの実行結果や、メモ帳で開いたときに見えるものです。

ですから、冒頭の `R-AXIS-CS 1.0-2.0` というテキストを16進数で表示した結果が `522d 4158 4953 2d43 5320
312e 302d 322e 30` ということになります。

> ヘッダー部だけをあらかじめ切り出し，拡張子をimgにしたファイルを使用していました．

上記の画面で範囲選択してコピーすると、16進数表記の文字列としてコピーされます。それを通常のSublimeText等に貼り付けて保存すれば、
**16進数表記のテキストファイル** になります。

Pythonで読み込むときではなく、切り出すときに形が変わっている、ということです。

* * *

ですから、バイナリのままPythonで読みこんで加工を行うか、前後に上記のような変換を行ったうえでPythonでテキストとして加工するか、どちらかになるでしょう。

なおSublimeTextでバイナリのまま切り出すには、次のような方法があるようです。

  * バイナリモードの状態でいらない部分を削除して、名前を付けて保存
  * 新しいタブに貼り付けて、 `File > Save with Encoding > Hexadecimal` で保存


CC BY-SA 3.0
2015-05-15T07:28:29.607
10217
2015-05-15T07:28:29.607
8000
10215
answer


[こっち](https://teratail.com/questions/9872) にも書きましたが、以下のように sublime
で表示される形式と同じ形式で出力すれば、バイナリとして読めていることがわかるでしょう。

[code]

    import binascii
    
    with open('sample.img', 'rb') as f:
        data = f.read()
    
    for i in range (0, len(data), 16):
        for j in range (0, 16, 2):
            print binascii.b2a_hex(data[i:i+16][j:j+2]),
        print
    
[/code]


CC BY-SA 3.0
2015-05-15T07:50:20.550
10218
2015-05-15T07:50:20.550
2494
10215
answer