Home > Tags > File

File

Android: リソースの画像ファイルの拡大・縮小描画 - drawBitmap()

画像ファイルの表示(拡大・縮小)

表示する画像はEclipse上でAndroidプロジェクト作成時に自動的に作成されるIcon画像です。
画像パス:プロジェクト名/res/drawable-hdpi/icon.png

resフォルダ以下に置かれたリソースはコンパイル時にプログラムに組み込まれます。その画像リソースを読み込む際は、

Bitmap BitmapFactory.decodeResource(Resources r, int resourcesID)

を用います。読み込んだBitmapインスタンスを描画するには、Canvasクラスのインスタンスメソッドである

void drawBitmap(Bitmap image, int x, int y, Paint p)

を使います。なお、拡大・縮小する場合も上記のdrawBitmapをオーバーロードしたものを使います。

void drawBitmap(Bitmap image, Rect src, Rect dst, Paint p)

今回のサンプルプログラムでは、元画像の幅と高さを2倍したイメージを描画しています。

ImageSp.java

package info.yukun.imagesp;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class ImageSp extends Activity {
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(new ImageView(this));
	}
}

ImageView.java

package info.yukun.imagesp;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.view.View;

public class ImageView extends View {

	private Bitmap image;

	public ImageView(Context context) {
		super(context);
		setBackgroundColor(Color.WHITE);

		// リソースの画像ファイルの読み込み
		Resources r = context.getResources();
		image = BitmapFactory.decodeResource(r, R.drawable.icon);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// イメージ描画
		canvas.drawBitmap(image, 0, 0, null);

		int w = image.getWidth();
		int h = image.getHeight();
		// 描画元の矩形イメージ
		Rect src = new Rect(0, 0, w, h);
		// 描画先の矩形イメージ
		Rect dst = new Rect(0, 200, w*2, 200 + h*2);
		canvas.drawBitmap(image, src, dst, null);
	}
}

AIR: テキストファイルに書き込み - openAsync()、writeMultiByte()

AIR: テキストファイルに書き込み
AIRコンポーネントではローカルのファイルにアクセスすることができます。下記のコードは日本語を含むマルチバイトの文字列をテキストファイルに書き込む処理をします。

処理の手順

  1. FileStream#openAsync()かopen()メソッドの引数にFileインスタンスとFileModeのプロパティを設定して実ファイルのパイプに接続
  2. FileStream#writeMultiByte()でファイルに書き込み
  3. FileStream#close()でストリームを閉じる

ソースコード

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" title="シンプルテキストメイカー">
<mx:Script>
  <![CDATA[
  import mx.controls.Alert;

  private var choDir:File = File.documentsDirectory; // ダイアログの初期ディレクトリ
  private var saveFile:File;
  private var stream:FileStream;

  private function onSaveFileBut():void {
    choDir.addEventListener(Event.SELECT, onSelectSaveFile);
    choDir.browseForSave("テキストファイルに保存");
  }

  private function onSelectSaveFile(e:Event):void {
    saveFile = e.target as File; // 選択されたファイル
    choDir.removeEventListener(Event.SELECT, onSelectSaveFile);
    try {
      stream = new FileStream();
      stream.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorWriteFile);
      stream.openAsync(saveFile, FileMode.WRITE); // 書き込みmodeで開く(フツーのopen()でもOK)
      var str:String = txtArea_.text;
      // 改行文字と文字コードをOS標準のものに置き換えて書き込み
      str = str.replace(/\n/g, File.lineEnding);
      stream.writeMultiByte(str, File.systemCharset); // 実際に書き込み
    } catch (err:IOError) {
      progLab_.text = "IOError : " + err;
    } finally {
      if (stream != null) {
        stream.close();
      }
    }
  }

  // ファイル書き込みに失敗した場合
  private function onIOErrorWriteFile(e:IOErrorEvent):void {
    Alert.show("ファイルの書き込みに失敗", "エラー", Alert.OK, this);
    if (stream != null) {
      stream.close();
    }
  }
  ]]>
</mx:Script>
  <mx:VBox x="0" y="0" height="100%" width="100%">
    <mx:HBox width="100%">
      <mx:Button label="ファイルに保存" id="saveBut_" click="onSaveFileBut();"/>
      <mx:Label id="progLab_"/>
    </mx:HBox>
    <mx:TextArea width="100%" height="100%" id="txtArea_"/>
  </mx:VBox>
</mx:WindowedApplication>

リファレンス

AIR: テキストファイルを非同期に読み込む - openAsync()、readMultiByte()

AIR: テキストファイル読み込みの実行結果
AIRコンポーネントではローカルのファイルにアクセスすることができます。下記のコードは日本語を含むマルチバイトのテキストファイルを読み込み、画面い表示する処理を行います。

大まかな手順

  1. FileStreamのコンストラクタの引数に対象のファイルへのパスが設定されたFileインスタンスを渡す。
  2. FileStream#openAsyncで実ファイルへのパイプ接続。
  3. この時、非同期の読み込み完了/エラーを取得するためにイベントを登録しておく。
  4. 実際の文字の読み取り(どれだけ読むか、文字コードの変換など)はFileStream#readMultiByteで行う。
  5. ストリームのインスタンスには接続時にpositionプロパティ(何処読んでいるかのポインタみたいなもの)からファイル末尾までのサイズ(bytesAvailable)を取得してるので、読み込みサイズにそれを指定。
  6. FileStream#close()でストリームを閉じる

ソースコード

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
  title="テキストビュワー">
  <mx:Script>
    <![CDATA[
    import flash.filesystem.*;
    import mx.events.*;
    import mx.controls.Alert;

    private var choDir:File = File.documentsDirectory; // 開くディレクトリを指す
    private var curFile:File; // 選択されたファイル
    private var stream:FileStream;

    private function onOpenFileBut():void {
      choDir.addEventListener(Event.SELECT, onSelectFile);
      choDir.browseForOpen("開く"); // ファイル選択ダイアログの表示
    }

    // ファイルが選択されたイベント
    private function onSelectFile(e:Event):void {
      txtArea_.text = "";
      stream = new FileStream();
      curFile = e.target as File;
      stream.addEventListener(Event.COMPLETE, onCompleteReadFile);
      stream.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorReadFile);
      stream.addEventListener(ProgressEvent.PROGRESS, onProgReadFile);
      stream.openAsync(curFile, FileMode.READ); // 非同期読み込み
      curFile.removeEventListener(Event.SELECT, onSelectFile);
    }

    private function onCompleteReadFile(e:Event):void {
      try {
        // OS標準の文字コードで読み込み
        var str:String = stream.readMultiByte(stream.bytesAvailable, File.systemCharset);
        // OS標準の改行文字への変換
        var pat:RegExp = new RegExp(File.lineEnding, "g");
        str = str.replace(pat, "n");
        txtArea_.text = str; // テキストエリアに表示
        stream.removeEventListener(Event.COMPLETE, onCompleteReadFile);
        stream.removeEventListener(IOErrorEvent.IO_ERROR, onIOErrorReadFile);
        stream.removeEventListener(ProgressEvent.PROGRESS, onProgReadFile);
      } catch (err:Error) {
        progLab_.text = "IOError: " + err;
      }
      finally {
        // パイプのクローズ
        if (stream != null) {
          stream.close();
        }
      }
    }

    private function onIOErrorReadFile(e:IOErrorEvent):void {
      Alert.show("ファイルを読み込み不可", "Error", Alert.OK, this); // 第4引数には親オブジェトを渡す
      if (stream != null) {
        stream.close();
      }
    }

    private function onProgReadFile(e:ProgressEvent):void {
      progLab_.text = "Progress: " +  e.bytesLoaded + " / " + e.bytesTotal + " bytes";
    }
    ]]>
  </mx:Script>
  <mx:VBox x="0" y="0" height="100%" width="100%">
    <mx:HBox width="100%">
      <mx:Button label="ファイルを開く" id="openBut_" click="onOpenFileBut();"/>
      <mx:Label id="progLab_"/>
    </mx:HBox>
    <mx:TextArea width="100%" height="100%" id="txtArea_"/>
  </mx:VBox>

</mx:WindowedApplication>

リファレンス

Python: ファイル読み込み時の例外の扱い例 - try、except、else、finallyブロック

ファイルのパスや名前のミス、パーミッションの権限が無い等が原因でファイルを読み込めない場合があります。そのような場合、すなわち例外が発生した際にそこで処理を中断して、発生した例外に合わせた処理ブロックにジャンプする構文が、try:~except Error:~構文です。

今回は、コマンドライン引数で英文テキストファイル名を指定し、スクリプト内でファイル内容を読み込み、単語数をカウントし出力するスクリプトを以って、オプションのelse、finallyブロックを含めた例外ブロックの扱いを確認します。
ただし、ここでの「単語」とは、1つの空白文字で区切られた文字列とします(簡単に)。

ソースコード

# -*- coding: UTF-8 -*-

import sys

script_name = sys.argv[0]
try:
    arg = sys.argv[1]
    f = open(arg, 'r')
except IndexError:
    print 'Usage: %s TEXTFILE' % script_name
except IOError:
    print '"%s" cannot be opened.' % arg
else:
    print arg, 'contains', len(f.read().split(' ')), 'words.'
    f.close()
finally:
    print 'n"%s" process end.' % script_name
    quit()
print 'Not reach this line.'

コードの説明

tryブロック

まず、例外を発生させる恐れのある行は、tryブロック内に書きます。

ここで発生しそうなのは、コマンドライン引数が格納されているリストへのアクセス部分であるsys.argv[1]です。[]演算子で存在しない要素を参照するエラー、もとい例外が発生する恐れがあります。

また、ファイルを開くopen(arg, 'r')も冒頭の理由で例外を発生させるかもしれません。

exceptブロック

exceptブロックは、tryブロックで例外が発生した場合にのみ実行されるブロックです。その為、例外が発生しない場合は実行されません。

発生する可能性のある例外のタイプ毎にexceptブロックを書けば、そのタイプ毎の例外への対処処理を書くことが出来ます。

except TYPE_AError:
    TYPE_AErrorが発生した際のとある処理...
except TYPE_BError:
    TYPE_BErrorが発生した際のとある処理...

elseブロック (オプション)

elseブロックは全てのexceptブロックの後に書きます(任意なので書かなくても構わない)。

elseブロックはtryブロックで例外が発生しなかった場合にのみ実行されるブロックです。今回は、ファイルの読み込みとクローズに使用しています。

finallyブロック (オプション)

finallyブロックはtryブロックで例外が発生するしないに関わらず実行されるブロックです(任意なので書かなくても構わない)。

実行結果

読み込むテキストファイルを以下のaLine.txtとします。
aLine.txt

Unless I set the standard where I am in any level, I'll be puzzled about what I should do from now on.

コマンドラインで適切な引数を与えた場合

$ python excp01.py aLine.txt
aLine.txt contains 22 words.

"excp01.py" process end.

存在しないファイル名を引数を与えた場合

$ python excp01.py texfile.tex
"texfile.tex" cannot be opened.

"excp01.py" process end.

コマンドライン引数を与えなかった場合

$ python excp01.py
Usage: excp01.py TEXTFILE

"excp01.py" process end.

例外オブジェクト名をpython処理系に聞いてみる

どんなメソッドや関数、演算子が、どのような例外を投げるのか予測が付かない場合があるかと思います。
そんな場合でもとりあえずスクリプトを実行してエラーを確認してみましょう。
SyntaxError: invalid syntax以外のエラーがある場合、例えば、

$ python excp01.py
Traceback (most recent call last):
  File "excp01.py", line 5, in 
    arg = sys.argv[1]
IndexError: list index out of range

のような場合は、最終行の行頭のIndexErrorが例外名となります。

何でも例外任せにしていいの?

計算量からみてあまり良いとは言えません。今プログラムのコマンドライン引数の確認を、
if len(sys.argv) != 2: ホニャララ
とすると整数の比較ですみますが、例外のキャッチに任せると、例外インスタンスを生成し送出するという、結構な計算量がかかります。ネットワーク接続やファイル読み書きなどのIOでは有効ですが、それ以外では積極的に使わないほうがいいかもしれません。

ドキュメント

Rで統計: CSVファイルの読み込み - read.csv()メソッド

読み込むCSVファイルは2007年度のセリーグの打撃成績の順位です。

参考:2007年度 セントラル・リーグ 個人打撃成績(規定打席以上)

batting2007.csv

順位,打率,安打
1,0.346,193
2,0.343,204
3,0.318,172
4,0.313,177
5,0.31,175
6,0.308,155
7,0.302,122
8,0.302,118
9,0.3,120
10,0.3,139

プロンプト

> read.csv("batting2007.csv")
   順位  打率 安打
1     1 0.346  193
2     2 0.343  204
3     3 0.318  172
4     4 0.313  177
5     5 0.310  175
6     6 0.308  155
7     7 0.302  122
8     8 0.302  118
9     9 0.300  120
10   10 0.300  139
> batting$安打
 [1] 193 204 172 177 175 155 122 118 120 139

read.csv()メソッドでCSVファイルを読み込み、そのデータフレームをbatting変数に格納しています。

実行結果を見ると、ファイル1行目のフィールド(列)名が変数名を表し、2行目以降がテーブル本体を表していることが分かります。これによって、例えば安打の列を抽出したい場合は、batting$安打と指定すればOKです。

ただ、毎回々々「batting$安打」と指定するのは億劫ですので、以下のコマンドで簡略化します。

> attach(batting)
> 安打
 [1] 193 204 172 177 175 155 122 118 120 139
>

attach()関数によってワークスペースにオブジェクトが保存され、データフレーム内の変数名のみでのアクセスが可能になります。

read.csv()メソッドのheader引数にFALSEを指定した場合

read.csv()メソッドはデフォルトでheader引数にTRUEが指定されていますが、以下のようにFALSE(必ず大文字)を指定することも出来ます。その場合の動作は以下のようになります。

> batting <- read.csv("batting2007.csv", header=FALSE)
> batting
     V1    V2   V3
1  順位  打率 安打
2     1 0.346  193
3     2 0.343  204
4     3 0.318  172
5     4 0.313  177
6     5  0.31  175
7     6 0.308  155
8     7 0.302  122
9     8 0.302  118
10    9   0.3  120
11   10   0.3  139
> batting$V3
 [1] 安打 193  204  172  177  175  155  122  118  120  139
Levels: 118 120 122 139 155 172 175 177 193 204 安打
>

ファイル1行目の列名がテーブル本体のデータセットに組み込まれていることが分かります。この場合の列へのアクセスは上の実行結果から、batting$V3と分かります。フィールド(列)名(一行目)を省略したCSVファイルを読み込みたい場合にはこのオプション引数を指定します。

Page 1 of 3123

Home > Tags > File

バックナンバー
最近のコメント
最近のトラックバック
メタ情報

Return to page top