プログラムで余りを出すときの高速な、小ネタ(2の倍数限定)
この間、Long型で16の余りを大量に処理が必要があったため
、割り算以外の方法を使用しました。(2の倍数限定)
●普通は割り算で以下の様に書くと思います
long num;
num = 30000000 % 16;
CPUの命令クロックは21くらいになると思います(多分)
●andを使用すると以下の様に書けます
long num;
num = 30000000 & 0x000f; //0x000f = 16-1
CPUの命令クロックは1くらいになると思います(多分)
以上 小ネタ
OpenCVにてCameraのInput Size変更してViewにOutputする時 BitmapErrerが出るときに対処(Android)
AndroidのOpenCVにてCameraのInputをTextureViewに出力する時
MatのRotationやResizeを行い、return Mat;をするとBitmap系のErrerが出ます。
用途:カメラの向きが90度傾いているのを戻したい、高速化のためshrinkにしたMatをEnlargeしたくない。
エラーが起きている場所は、"CameraBridgeViewBase.java"の、MatをBitmapに変換する処理の様です。
以下のメソッドに
protected void deliverAndDrawFrame(CvCameraViewFrame frame) {
Mat modified;
if (mListener != null) {
modified = mListener.onCameraFrame(frame);
ReturnしたMatをBitmapに引き渡す処理がありますが、(その先は未解析)
BitmapSizeはCameraのPreviewSizeで初期化された後、Mat Size合わせて変更する処理が無いため、Cameraと違うMat SizeをmCacheBitmap入れると怒られてしまします。
Utils.matToBitmap(modified, mCacheBitmap);
ですので、以下の様にメソッドに追加します。(自己流:modifiedのサイズでBitmapを再生成:mScale値は不要です。)
(追加箇所://add :mat AutoFIt :Start と //add :mat AutoFIt :End の間の処理)
/**
* This method shall be called by the subclasses when they have valid
* object and want it to be delivered to external client (via callback) and
* then displayed on the screen.
* @param frame - the current frame to be delivered
*/
protected void deliverAndDrawFrame(CvCameraViewFrame frame) {
Mat modified;
if (mListener != null) {
modified = mListener.onCameraFrame(frame);
} else {
modified = frame.rgba();
}
boolean bmpValid = true;
if (modified != null) {
try {
//add :mat AutoFIt :Start
if(modified.cols() != mCacheBitmap.getWidth() || modified.rows() != mCacheBitmap.getHeight()){
Log.d(TAG, " mCacheBitmap.getWidth():" +mCacheBitmap.getWidth() +" mCacheBitmap.getHeight():" +mCacheBitmap.getHeight());
mCacheBitmap = Bitmap.createBitmap(modified.cols(), modified.rows(), Bitmap.Config.ARGB_8888);
float scaleHeight = (float) mFrameHeight/ (float) modified.rows() ;
float scaleWidth = (float) mFrameWidth / (float) modified.cols();
mScale = scaleWidth > scaleHeight ? scaleWidth: scaleHeight;
Log.d(TAG, " mScale:" +mScale +" scaleWidth:" +scaleWidth
+" scaleHeight:" +scaleHeight
+" mMaxWidth:" +mMaxWidth +" mMaxHeight:" +mMaxHeight
+" mFrameWidth:" +mFrameWidth +" mFrameHeight:" +mFrameHeight
+" modified.cols():" +modified.cols() +" modified.rows():" +modified.rows());
}
//add :mat AutoFIt :End
Utils.matToBitmap(modified, mCacheBitmap);
} catch(Exception e) {
Log.e(TAG, "Mat type: " + modified);
Log.e(TAG, "Bitmap type: " + mCacheBitmap.getWidth() + "*" + mCacheBitmap.getHeight());
Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage());
bmpValid = false;
}
}
if (bmpValid && mCacheBitmap != null) {
Canvas canvas = getHolder().lockCanvas();
if (canvas != null) {
canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
if (BuildConfig.DEBUG)
Log.d(TAG, "mStretch value: " + mScale);
if (mScale != 0) {
canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(), mCacheBitmap.getHeight()),
new Rect*1 / 2),
(int)*2 / 2),
(int)*3 / 2 + mScale*mCacheBitmap.getWidth()),
(int)*4 / 2 + mScale*mCacheBitmap.getHeight())), null);
} else {
canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(), mCacheBitmap.getHeight()),
new Rect*5 / 2,
(canvas.getHeight() - mCacheBitmap.getHeight()) / 2,
(canvas.getWidth() - mCacheBitmap.getWidth()) / 2 + mCacheBitmap.getWidth(),
(canvas.getHeight() - mCacheBitmap.getHeight()) / 2 + mCacheBitmap.getHeight()), null);
}
if (mFpsMeter != null) {
mFpsMeter.measure();
mFpsMeter.draw(canvas, 20, 30);
}
getHolder().unlockCanvasAndPost(canvas);
}
}
}
Gmailのメール本文(body)の取得
Gmailのメール本文を取得するのに、意外とはまったのでメモ
Message を使用するとFromとSubject 他は容易に取れるのにBodyが取れない!!
ってことで大分はまりました。
環境:AndroidStudio2.2.3 API :javax.mail 接続IMAP メールBody:plainText
- MessageクラスのgetContent()で取ると戻り値が空白?
message.getContent()
- getContent()を.toString()すると以下のハンドルを返す?(inputStreamらしい)
message.getContent().toString()
>>>>com.sun.mail.imap.IMAPInputStream@3885acf
- 結果以下の方法で動くことを確認
- 以下のおまじないclassを用意(importは聞かれるままに…)
public static String readString(InputStream inputStream) throws IOException {
ByteArrayOutputStream into = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
for (int n; 0 < (n = inputStream.read(buf));) {
into.write(buf, 0, n);
}
into.close();
return new String(into.toByteArray(), "UTF-8"); // Or whatever encoding
}
- bodyを呼び出す
Body = readString(mMessage.getInputStream());
- メールの取得用メモ
Message mMessage = hogehoge.getMessages();
Email_Number = mMessage.getMessageNumber();
Subject = mMessage.getSubject();
From = mMessage.getFrom()[0]; //1件のみ取得
Body = readString(mMessage.getInputStream());
Date = mMessage.getSentDate();
Subjectまでは簡単だったのに…。
あとreadString()の引用元が分からなくなったので誰か教えて…。
画像配列(0-255値)を高速にグレー処理する小ネタ(色覚特性は無視しています)
画像配列の処理結果(0-255値)をRGBグレーの配列に置き換えたい時の小ネタ
グレー処理の基本はRGBの値に0から255の値を入れる事と思っています。
RGBの各色に色覚特性の重みづけを行うことも多いですが、今回は無視。
Bitmapクラスに入れる前に、int Value(0-255値)を、int BitmapRGB値に変換します。
- よくある方法ーbitシフトとbit orで生成する。(例:java)
public int[] valueToGray(int[] imageValue ){
//imageValueの値は0-255の範囲とする
int mGray;
int [] ImageStore =new int [imageValue.length];
for (int i = imageValue.length - 1 ; i >= 0 ; i--){
mGray = imageValue[ i ];
ImageStore[i] = mGray | mGray << 8 | mGray << 16;
}
return ImageStore;
}
- 掛け算の原理を使用すると以下の様に変換できる
public int[] valueToGray(int[] imageValue ){
//imageValueの値は0-255の範囲とする
int mGray;
int [] ImageStore =new int [imageValue.length];
for (int i = imageValue.length - 1 ; i >= 0 ; i--){
mGray = imageValue[ i ];
ImageStore[i] = mGray * 0x00010101;
}
return ImageStore;
}
結果は同じで、javaで実行すると3倍くらい早い。
以上小ネタ。
Android Studio のAVDでカメラエラーの記録、覚え書き
ある日、Android StudioのAVDでWebカメラが使用できないことに気が付きました。
OS:Windows10
起動時に以下のエラーを吐きカメラが使用できません。
”emulator: ERROR: cmd_camera_device_start_capturing: Device 'AndroidEmulatorVC0' is unable to save frame to the clipboard: 0”
気が付くまで、2週間ほどたってしまい、原因があやふやに…。(Googleさんから他の注意を受けて対応をしていたため)
取りあえず使えていた状態に戻すべく、Google先生に質問!
解決したと思われる投稿が無い…。
Answer:「実機でテストすることにした」「Javaのクリップボードを無効にしていないか」「コマンドを打ちWebカメラを選び直せ(画面すら出ない…)」
Android: How to use webcam in emulator? - Stack Overflow
嫌な予感がする。
でも、他の優先事項があるので一旦保留。
(システムの復元は過去に色々痛い思い出、あまりしたくない…)
パソコンで変えたことと言えば…。
WindowsとAndroidStudioのUpdete、JavaのUpdete他、要らないソフトのアンインストール
数日後…
とりあえず、AndroidStudioとJavaを最新に再インストールすれば治るかなと
思い、AndroidStudioとJavaも最新アップ
→変わらず…。
押してもダメなら引いてみなで、ダウングレード。
AndroidStudioとJavaを2016年8月の物で再インストール
→変わらず…。
ゴミが残っているのかなと思い、アンインストール後、以下を削除後、古いバージョンでインストール。
C:\Users\<AccountName>\.android
\.AndroidStudio1.4
\.gradle
C:\Users\<AccountName>\AppData\Local\Android
C:\Program Files\Android
C:\Users\<AccountName>\AppData\Roaming\Sun
C:\Users\<AccountName>\AppData\LocalLow\Sun
→変わらず…。
一応、SDK Managerで以下も改めてインストール
・Google USB Driver
・Intel x86 Emulator Accelerator
Webカメラが壊れた可能性も考え。(エラー内容からしても可能性は低いですが)
カメラソフト(AGCRec)で確認すると、映像が表示されます。
いまさらであるが、エミュレータの流れを考える。
Emulator.exe→avd→java→Windows→USB→カメラ
残りはWindowsとカメラのドライバ
(Windowsは極力避けたい…)
カメラのドライバを削除し再度セットアップする。(ドライバを変更したことは無いが、昔は他のDLL導入削除で動かなくなったことを思い出し。)
→変わらず…。
カメラのドライバキャッシュを削除する。
削除方法:
ドライバ削除後、infファイル、sysファイル等全て削除しましたが、Windowsの起動後、自動的にドライバがインストールされてしまいます | BUFFALO バッファロー
→変わらず…。
プロファイルの問題と思い、アカウント作成しログイン!
→やはり、変わらず。ただシステムの問題であることが確定したのは収穫。
ふと、Google先生に”Java”と”logicool”で何か出るかなと思い
ゲーム開発の情報の中、気になる記事が!
「Logicool ウェブカメラにネイティブの UVC ドライバをインストールする - Logicoolサポート記事」
そういえば、昔やったような。
今さらながら、確認するとドライバの製造元がLogicoolになっています。
早速上記サイトの手順を実施し、製造元がMicrosoftに変更!
手順
・[デバイス マネージャ]を起動。
└[イメージング デバイス] を展開。
└[Logicool カメラ]を右クリック。
・[ドライバ ソフトウェアを更新...] を選択。
・[コンピュータを参照してドライバ ソフトウェアを検索する] を選択。
・[コンピュータ上のデバイス ドライバのリストから選択する] を選択。
・[互換性のあるハードウェアを表示] にチェックを付けて、[USB ビデオ デバイス] を選択。
・[次へ] をクリックし、あとはポジティブ指示を選択しながら更新。
無事エラー無く起動するようになりました。
WindowsのUpdateが原因かと、思いにふける…。
はじめまして、適当に書きます。
よろしくお願いいたします。