アラのアラアラしい日記

こっそりかいてます

RaspberryPiとICカードリーダ

こんにちは!つま先に手が届かない人です。

今回は久しぶりのraspiネタです。
非接触ICカードリーダを買ったので、それを使ってICカードのIDをとるまでのメモを残しておきます。

買ったのはこれ。
www.sony.co.jp
SONYのRC-S380です。raspi系でこれを使ってる人をよく見かけるのと比較的新しいモデルなので購入しました。

こんな感じです。
f:id:wknar0311:20150813162046j:plain

まず、PythonからUSBを使う為のパッケージをインストールします。

$ sudo apt-get install python-usb

次にNFC規格カードを読み書きする為のnfcpyをダウンロードします。

$ wget https://launchpad.net/nfcpy/0.10/0.10.0/+download/nfcpy-0.10.0.tar.gz
$ tar xvzf nfcpy-0.10.0.tar.gz

nfcpyの最新バージョンはこちらから確認できます。

解凍したディレクトリ内にいくつかサンプルスクリプトがありますが、
カードの読み取りはtagtool.pyというファイルの実行で行えます。

$ sudo nfcpy-0.10.0/examples/tagtool.py

これにより、以下のような結果が取得できます。
(それぞれの値は実際の値ではありません。)

IDm=031402145812f56f PMm=140b4b498435e0ff SYS=a283

意味は以下の通りです。

名前 意味 説明
IDm 製造ID カードを識別する為のID
PMm 製造パラメータ カードの種別と性能を識別する為のパラメータ
SYS システムコード システムを特定する為の値で、事業者および使用目的ことに割り当てられる

詳細はこちらからどうぞ〜

IDmがカードごとに振り分けられているユニークなIDです。
今の私の持っているカードでは、SUICA, nanaco, edyで読み取ることが出来ました。
アミュパスはダメでした(真顔)

他のデバイスとの組み合わせを考えているので、
何か完成しそうになったらまた書こうと思います。

android開発メモ

こんにちはニンジャです。暑くて圧倒的に脳が動いていません。
今回はandroid開発で困って調べたりした小さいメモ群団をここに残しておきます。
間違いとかフワッとしていることが多いので、自己満エントリですすみませんでした。

android commandを使えるようにする方法

android studioが既に入っている場合、
以下でandroid系のコマンドが使えるようになります。

export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$ANDROID_HOME/tools:$PATH
export PATH=$ANDROID_HOME/platform-tools:$PATH

これによってemulatorコマンドやadbコマンドも利用可能になります。

android studioでアプリやテストの実行

android studioでアプリを実行すると、INSTALL_FAILED_NO_MATCHING_ABISというエラーが起こることがあります。
ABIは「Application Binary Interface」の略で、ネイティブライブラリを使うアプリなのにABIがそれをサポートしていない為に起こるエラーです。

私がこのエラーに直面した時は、実行したアプリがカメラライブラリを利用するものでしたのでこれが起きました。

特にABIx86はネイティブライブラリをカバーしていないものが多い為、エラーが出ることが多いようです。
その場合は、ABIx86以外のデバイスを使用すると実行できるようになります。
(android studioでのemulatorの追加方法はこちらのリンクが参考になります。)

PCにインストールされている機種一覧は、

ls ~/.android/avd/

でも確認できます。

emulatorのカメラが動作しない場合

macandroid emulatorを起動する場合は、AVDマネージャの"Show Advanced Settings"から起動するカメラ(webcam等)を選んでおいてから、
Photo Boothをバックグラウンドで実行している必要があります。
Photo Boothなしで起動すると、emulator: ERROR: Unrecognized pixel format 'v024'のようなエラーが起こります。
iOSの場合はemulatorでカメラが起動できませんので、これは結構便利だと思いました。(撮った写真等はライブラリに保存も出来ます。)

androidでBitmapを縦横比を維持しながらスケールする方法

こんにちは!メガネ萌えする人です!
今回はandroidネタです。

ビデオのサムネイルをBitmapで取得した時の表示のさせ方について、若干はまったのでメモです。
サムネをレイアウトの中で3:4の比率で表示させようとした時に、思ったように拡大縮小されなかったんですね〜
ただ、調べていると色々な方法があるようなので、その中の一つとして見てもらえればと。

fileName = "***動画ファイル名***"

// サムネイルをBitmapとして取得
Bitmap bmp = ThumbnailUtils.createVideoThumbnail(CommonUtils.getAvailableDirectory() + fileName, MediaStore.Video.Thumbnails.MINI_KIND);

// 作られたサムネイルから横幅とそれに応じた高さを指定
int dispWidth = bmp.getWidth();
int dispHeight = dispWidth * 3 / 4;

// 元のサイズでBitmap作成
bmp = Bitmap.createBitmap(bmp, 0, 0, dispWidth, dispHeight, null, true);

// デバイスの画面サイズを取得
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);

// スケールさせたい大きさを指定
int scaleWidth = size.x / 2;
int scaleHeight = scaleWidth * 3 / 4;

// 上で指定した大きさにする為にLayoutParamsを指定
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(scaleWidth, scaleHeight);

// 指定したparamsをセットしてokomeThumbViewにBitmap表示
okomeThumbView.setLayoutParams(params);
okomeThumbView.setImageBitmap(bmp);

BitmapクラスにはcreateScaledBitmapというメソッドも存在するのですが、
機種によって勝手にトリミングされたりして思ったようにサムネイルが取得出来ない場合がありました。

また、最初からscaleWidthscaleHeightcreateBitmapを実行すると、
今回の場合はscaleWidthをデバイスの画面サイズから作っている為、
元のbmp.widthがscaleWidthよりも小さい場合にエラーが起こります。(これも機種に依存するエラーです。)

それにしても圧倒的javaアレルギーだった私ですが、androidを始めてからjavaアレルギーがなくなった気がします。
個人的にはiOSよりもandroidの方が自由度が高いので開発は楽しかったかなーという感想です。
android studioxcodeがもっと仲良くなって同じ仕様になってくれたら嬉しいですねww (ショートカットとか)

AVAssetImageGeneratorから取得した動画のサムネイル(UIImage)が撮影時とサイズが違ってしまう問題の解決法

こんばんわ!一昨日の晩御飯が思い出せない系エンジニアです。
objective-cを「おぶしー」って呼んでいたらチャラいって言われました。

そんな感じで、今回ハマったのはAVAssetImageGeneratorから動画のサムネイルを取得したあとに、それをUIImageで画像として表示するところで、
なんだか撮影していた時と表示される画像のサイズが違ったのでその解決法を書きます。

私が遭遇した現象としては、以下のような感じです。
f:id:wknar0311:20150531115654p:plain AVFoundation Frameworkを使用しているのですが、この撮影範囲とiOSカメラの撮影範囲が違う為、
画像に変換した時に撮っていた時と違う表示のされ方をします。
見てくださいよこの可哀想なカーネルサンダース。
( というかAVFoundationで撮影している時点で全体の画像を持っているんですね。)

色々調べていたんですがどれも理想通りにいかなかったので、
以下のようにしました。

// サムネイル作成
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[videoFile toURL] options:nil];
AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
gen.appliesPreferredTrackTransform = YES;
CGImageRef image = [gen copyCGImageAtTime:CMTimeMakeWithSeconds(0.0, 600) actualTime:nil error:nil];
UIImage *thumb = [[UIImage alloc] initWithCGImage:image];
CGImageRelease(image);

NSString *attr = [[NSString alloc] initWithFormat:@"okomeView%d", i];

// ここでサムネイルの余計な部分を切り取る
[[self valueForKey:attr] setContentMode:UIViewContentModeScaleAspectFill];
[[self valueForKey:attr] setClipsToBounds:YES];
[[self valueForKey:attr] setImage:thumb];

取得したサムネイル画像からUIViewContentModeを利用して見た目を変えてしまうという方法です。

UIViewContentModeScaleAspectFillで元の縦横比を維持したまま、指定した範囲内で最大に画像を表示します。
そのあと、setClipsToBoundsYESにすることではみ出した部分を非表示にします。
これで撮影した部分のみのサムネイルが表示されます。

ただ、切り取り済みの画像を表示するのと違い、表示毎に大きい画像を持ってきてから見た目を変えたり非表示にしているので
メモリ使用量を考えると大量のサムネイルを表示したい時等は向いてないかもしれないです!

UIViewContentModeの使い方は以下から見れます。
UIView Class Reference

それではちゃんと歯磨きして寝てくださいね!

objective-cのループ内での表示とか非表示とか

こんにちは!okomeが好きな人です。

相変わらず仕事でobjective-cを触る毎日ですが、
地味に時間がかかってしまったのでメモです。

Storyboardを使って画像を表示するような場合、

@property (weak, nonatomic) IBOutlet UIImageView *okomeView;

このように変数を定義して、

UIImage *okomeImage = [UIImage imageNamed:@"okome.png"];
self.okomeView.image = okomeImage;

と、指定した変数に対して画像をセットするのがありがちだと思いますが、

例えば3つの画像を並べて表示したい場合、以下のように変数を定義して、

@property (weak, nonatomic) IBOutlet UIImageView *okomeView0;
@property (weak, nonatomic) IBOutlet UIImageView *okomeView1;
@property (weak, nonatomic) IBOutlet UIImageView *okomeView2;

「よしループで表示だ!」と思ったらobjective-cの場合は変数のループってどうやってまわすんだってなってしまったんですよね。。。

そこで、調べてみると表示方法にもいくつか種類があることを知りました。
先程の画像の表示を違う方法で書くと以下のようになります。

  [[self okomeView] setImage:okomeImage];

この表示方法を利用すると、以下のようにループ文を書くことが出来ます。

for (int i=0; i<3; i++) {
  NSString *attr = [[NSString alloc] initWithFormat:@"okomeView%d", i];
  [[self valueForKey:attr] setImage:okomeImage];
}

流れとしては、最初にokomeView{i}になるような文字列をセットして、
それを利用して先程の表示方法を書きます。

この方法を利用すると以下のようなhiddenなども指定することが出来ます。

  [[self okomeView] setHidden:YES];

set系の関数むちゃくちゃ多いので色々出来そうですね。

もっと良い書き方とかを知っている方は教えてください!

objective-cでdelegateを使ってmodalのtextareaつくるよ

こんばんわ!
天一はこってりしか食べない人です。

最近会社でのポジションがウェッブエンジニアからiOSエンジニアになったのですが、
objective-cxcodeの文化ってありますね!初めてpython触った時のインデントみたいな!(雑)

という訳でmodalで出てきたウィンドウからテキストを入力して、
modalを閉じたら元の画面に入力したテキストが表示されてるっていうのを作るコードが
意外と分かりやすいマニュアルとか参考が少なかったのでメモしておきます。

元の画面名がFirstViewController, modal画面名がModalControllerです。

●FirstViewController.h

#import <UIKit/UIKit.h>

@interface FirstViewController : UIViewController {
}
@end

FirstViewController.hに関してはデフォルトのままで大丈夫です。

●FirstViewController.m

#import "FirstViewController.h"
#import "ModalController.h"

@interface FirstViewController ()
@property (weak, nonatomic) IBOutlet UILabel *viewLabel;
@end

@implementation FirstViewController

- (void) viewDidLoad {
    [super viewDidLoad];
}

- (void)sendOkome:(NSString*) str {
    self.viewLabel.text = str;
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    NSString *genmaiText = self.viewLabel.text;
    ModalController *mCon = [segue destinationViewController];
    mCon.mydelegate = self;
    mCon.genmai = genmaiText;
}
@end

viewLabelはModalInputControllerで入力したテキストを表示する部分です。
ModalControllerに送りたい(ModalControllerインスタンスを使いたい)ので、初めにModalController.hをimportしておく必要があります。 prepareForSeguemethodでボタンが押された時にgenmaiとしてModalControllerにテキストを送ります。

●ModalController.h

#import <UIKit/UIKit.h>

@protocol ModalControllerDelegate
- (void)sendOkome:(NSString*)str;
@end

@interface ModalController : UIViewController <UITextViewDelegate> {
}
@property (nonatomic, weak) IBOutlet UITextView* textOkome;
@property (weak, nonatomic) IBOutlet NSString *genmai;
@property (nonatomic, retain) id mydelegate;

@end

受け取るデータの変数やdelegateの設定を行います。

●ModalController.m

#import "ModalController.h"

@interface ModalController ()
@end

@implementation ModalController
@synthesize textOkome, mydelegate, genmai;

- (void)viewDidLoad {
    [super viewDidLoad];
    textOkome.delegate = self;
    [textOkome becomeFirstResponder];
    textOkome.text = genmai;
}

- (BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)textGenmai {
    if ([textGenmai isEqualToString:@"\n"]) {
        [textView resignFirstResponder];
        return NO;
    }
    return YES;
}

- (IBAction)pushBtn:(id)sender {
    if ([self.mydelegate respondsToSelector:@selector(sendOkome:)]) {
        [self.mydelegate sendOkome:textOkome.text];
    }
}
@end

受け取った値をtextview内に表示し、textview内にあるテキストをdelegateで取得しています。
最後にFirstViewController.mのsendOkomeメソッドを呼び出してそこでmodalウィンドウを閉じています。

試行錯誤で出来たものなので美しくないですがつんだら試してみてください。
説明がまじで下手くそなので後日追加するかもしれません。

screenで絵文字が出ない人へメッセージ

Macのターミナルでtmuxは絵文字が出るのにscreenだと出ない!!
screenから抜けると出るのに!!

と言っているみなさん、brew info screenしてみてインストールされてなかったらbrew install screenしてみてください。インストールしてたら、brew update screenしてみてください。
そんで、ターミナル再起動してみてください。

きっと幸せになれます。
私が幸せになりました。