From d673197d01ee44865a5825f4317cc10ae8560353 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Tue, 28 Jun 2011 15:12:14 +0000 Subject: [PATCH] Added base Android Java sample --- samples/android/0-base/.classpath | 7 + samples/android/0-base/.project | 33 +++++ samples/android/0-base/AndroidManifest.xml | 29 ++++ samples/android/0-base/default.properties | 11 ++ samples/android/0-base/res/drawable/icon.png | Bin 0 -> 5760 bytes samples/android/0-base/res/values/strings.xml | 4 + .../src/org/opencv/samples/Sample0Base.java | 44 ++++++ .../src/org/opencv/samples/Sample0View.java | 137 ++++++++++++++++++ 8 files changed, 265 insertions(+) create mode 100644 samples/android/0-base/.classpath create mode 100644 samples/android/0-base/.project create mode 100644 samples/android/0-base/AndroidManifest.xml create mode 100644 samples/android/0-base/default.properties create mode 100644 samples/android/0-base/res/drawable/icon.png create mode 100644 samples/android/0-base/res/values/strings.xml create mode 100644 samples/android/0-base/src/org/opencv/samples/Sample0Base.java create mode 100644 samples/android/0-base/src/org/opencv/samples/Sample0View.java diff --git a/samples/android/0-base/.classpath b/samples/android/0-base/.classpath new file mode 100644 index 0000000000..6e9239ff0d --- /dev/null +++ b/samples/android/0-base/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/samples/android/0-base/.project b/samples/android/0-base/.project new file mode 100644 index 0000000000..d828d75c04 --- /dev/null +++ b/samples/android/0-base/.project @@ -0,0 +1,33 @@ + + + Sample 0 base + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/samples/android/0-base/AndroidManifest.xml b/samples/android/0-base/AndroidManifest.xml new file mode 100644 index 0000000000..344ace78c3 --- /dev/null +++ b/samples/android/0-base/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/android/0-base/default.properties b/samples/android/0-base/default.properties new file mode 100644 index 0000000000..787ee33afa --- /dev/null +++ b/samples/android/0-base/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-8 \ No newline at end of file diff --git a/samples/android/0-base/res/drawable/icon.png b/samples/android/0-base/res/drawable/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4e828bafd86aae740c6d4da0af6cc67653b535a5 GIT binary patch literal 5760 zcmZ`-XEfVw*#9R&Vz1ais1ma=O6(9LsG6~g+N(v7nytpJQM;&3OVOuBi`HmM)vjGN zYgFwTwG~fa&-?BD@LuO!_wT;exyF6Y_2G^;zNt%3!%YJK0KFbw%k&cQ|1pf}@+54% z(Y*wSyN00#0Mw<>o;y-r%Af#KT}_~R5V3wKAf551h5!&M3;^V40QhsMBCi3!Jv0Dp zH~@fB4ghcv^P5dnE)7&p2D)08cuA+YmWP)>O~hLV001rPe+&Y0^Ev-h1`;*gFY$j1 z0R}^MFO#w<>uG722TyP1hY*DX46n`M!sc7l0w?6{d6MeoAeahJ6S|C(amA*T)mR_{OZ3Blx(BPTCDm}&9H(21R{K0297$T)kbT&? z{dC03t=>Mx34h{!uR(t!{32}rxMhAv@;oct;9A^g@xw)aP&am##)cM>fFv(|;(E{sVUd)0q$Ws=+p zWO>#(*Y=N-!<*PaP(SF!kJsL)Ty#NPclz!WbdgZN1UknfZ%g<3VwNN5Jg98FJKpl< zs57QEXVZsL6`r!4pT;?e4AY$e%TEet`b*#7ucSw%QpR~>EVON;PDULUC1#KHg6W58 zAg6{;$~D?j7v!vW-5HYXCD2c@sk?yla~x5;mJ0S)Co&Vtj%`@@&TvBxoKKVb#d&w( z6_K`<&%x3dJ%X4LKhD} ziRY=yB1GFh^nAD7-&VL)IQ1oBOEK%yl3k*o}oe=17yFKJ35U9}{tV`*7 z)jW!cgxp2u-^wgH!g^J}Js)$gjrCx!0(amTy85qSYP8=nQp1^6hMF>19fBeQRfVb} zjsjud!1_Ro!wfxfR~b$HoD8P7Xov-o62mMPSU_hRs(DnKo9GaQq!i7*G?r995swFq z=e{xb_+!N7akpOiDG3Df*q-hXo$Mnsb@bD;qbeN50!7eL`&B_=yP;kXf9=|jlx9Uy zi+VYrE^_z+os1@DU;FMp`W?f8fn(xro#B2wpth^d@a)Q{`g4?l39iDC1)lxZ4HQ;E zaqijkfKu4a#Y>*>C#x> zxj>U;8P`VjVLpWl{Zo))yy)|9)mmj9xgj`#Sle1L`hSQuKUB`&ijLQcVYwgOd?YsP z)XyYAHs6WO)Z+#l55HHIIbfU!9n3;<;mPHxFI9IUoe4L3T4tp2VtY@ko=4)blZ*qD zPkTav>(SgY!?s*xHcLZ1axYWWGL5@>3gpf>X;a`ZmKBA`f(YZIWG`arNT1%X3V0jf zZapz)lHAKHr%f6(?X}j)6R7%TeC=odAUr1)Vfn1R-4_QaZOxgbzAoFW)(0_JV(ZIP z;&an~*N6GWzEAiv`!XGL9jHb^tgK03p&ys%V z4%5BTy%4lfAAa^HSZI%p0uS)V-328pk1|=7Nx>e{NqyuEM2$*9#ZNhPvgi#TQ7&B2 z%v$ZVxFdsf+zu$?Jw@O6!mdjgLof_0aFy?Ldi?*qJW2xpiYru)nNX+gjuTA#l~q`n z*4%qa=>_RhUiB+;N>Xr z^C3e(GQ^FKi~Q{%fdlurdK}hv%rr}a{VM=bee&?jOR?2PpJhuZqyOt?9rh3btPl%z zG}BshvLokYV*%soefR3n6|Sv>ZvOd^^nt3?88B~ti{pXW@Et7wuE7GAOY=xAK9r#U z#IvWBTVBW2tp{3yh#$!jSK^^pU-HmqzzD?`9hbd>d z5~^4=VdXDgP{(y(lA}CxbISG5oI>33=+pt3kAac}9UYHs2hVAe9`JTaJgv&t&>upN zvOj&C-&3_k#p%Ew5%Tx3!nVrW2WLLl5yE_lC7Vjk)y}zY>+Um+Blik!2;(q_uGbP0 z{h#Cv;o9vro=LgFl^$R3J2))-QjoYKAz9|igo)2AwC0vjt);R5a+L=yZ+DNN^4@pe z2RGr#NY(512DmJ233K&{KVqH8&dxq8_t;9pB3+{Y_2o@VP@~52QTOrIExg+CET?Hh zXxfo`EEPwe1sl?E3~e~}HfX4j=TOtJrQFj+hD)Mf6Sj_tVMbdP-P=yTFIRQ1a@ue`VU-sUu} zWSG9w$%H^)GaP%QCHQ&CZ+dzfZJ1G6DN5IYnnKJpT3cBa*VHg}piyudcw%R|5)~L! zI^r>Nv^5ieALlN&)wuiapsf=>%xSD8pbvWjqmjM=mw-_29mo!a_11XWy`i5R86DLW zViB!OTf+R@54l;Oq%D<=Gl7?mpb|<`^~-ve{SOWg)9^wts;J3EyHE}+jCros5%*)V z&Ux;p4$dqwkz(z8n*v$%etj)(%!B~u(d-}Z?hLIw30^v4bjBam(3ejde()jrL=!#@ z4>Pf{vR*zv3hw0PMKjZALTGrN@c#Y#yYnBun@x4jm{-Nv(pv;CgQ-siDZQc#c2l)CPcYHE)c(Boe# z`6_EYq-?aGRa7L4sgOx_-F^t0TemK!QKl!J5V?e@sM0qxV>L81B#}tQ66|$bGV`YC z5LwwQs`fzC=d|XfL$pQ7_ckZs(?gh3wwCyB>62idg9kkJoH(5Yg6iTP{!b!Vk5)}B zX2A&MYh#OH^ZRwSMH;e7sX`@qS+h5KXY?-{6W9bGx#em7%N{;H!klz0G%=4logiQk zOFZOvFv4!az@)*w8=<@WIsT@*W4j8}`Av_PlWT87q`j8KolZ4lbTQ7G`2gP|y2E2Z1FVM_85Y7|B{1PS-1lJ8n~7UH%&PAB6RF8&!VFwqUY8~%l^`zfCn zk4(!%pswMVIX%w8@t)l^)#?Y%mxbLNya`VNYY4Xig|G9_B>M#wMvM-CEpj z*gf&g$*;`GxyqyY4b&;W`;p^w*Typ%hhzKT{RU!+LRY%ab?V_mysX4z^un=K?-P-c zQ@*kDN7k{{5E6u{pdx4TKo)w#D(m{(#6-3#aiML-obZ@4w(f?F3dPpd7poZ@e2^&S zWPV?fj44JT;3N4$c_HEbZiawM@A$yV->EHww{MYoci#iw_Bz^%hc2QAK-d$03&d%K1K(uH`m8sOF1 z2;Z6n&Vo8l6kVo-cJ!ZJ0qFw)a?GpaJ=G%{aw)ypT&wn7bx$?25V5vs70dWAqbqmh z`xX|8w=g#y`m-bzVl_(~Et(NX{n~G@pe?bILN^^?qPoP8?NWyckgzenlzAGRvdPQiZ|I|6CMN9 zRkfA0=iiIp3L2mkU2c;_R!M?uRn*DJ9nU1tdegkcj7^g2`b~$g{LkLXBpHE+gfeWqv2L}hgFB0Er6UNhnm^B?{8VmZVsi;2neg5pWcZzE(lfu{=dH6CE>NSb0 z#wJ~uNd%2;YpRBTeG~~iNYFt&ww1oz#x~v-_#%U4F#Niyf4!DVIK>RSmfxT6j(Dm4 z`sTW~WnV(4lfQ?@+G*Wl-SI?ixc6s zR*8LfsJplh0dmrS0x%&sEZvmc(p1-T225&3HfFIr=E0BFWDg?}7tQ^ZEBe?w%0MYq{+WK!$Pl@oY%c5J3$80a3J&49x!N`?x=ISZj;nd`C=vqsa*60 zx4~E3?)Byn<%dQ|GaK?<__$VlRybUT+7#QVBM{N2HnIKHXecH92U>))jBzUcL}*XQ z-2!|zxw*J7ft)l8LfnPYyfOYo=}mK=-Gkb=k^DM~Eyzchbb{qS4+erk!3az;oom)l zH85-!^)}5N;?DM0(!n44ppBxv!5r3 z4wV}$anji(W<9oI{jV$Te~VwxgCc#GRhwu_ttmbzfo}6geS*J!up%V$@rDUA zWMYHywPK%&quW#)RVk^sHAx2w4KCDHYgY{a1PQGCy)HD0eo+w~-5WtoF__eDqfYXU zZ8Mm6wbs<*{nrPv%@@<@d3+{f7cRy)ZcK};F?amU8Sq6`gU93tiK*>xx~nI96f|ea zmutmQ*pB!ott?%(=WC-y>H3~be%y=h;$Ct&M60y;{pXb$ZQ8_v+J&O^t^hL!v#KfN&pF=1Vcv^XM(B|)z*Js?*J`g`NCM5?qF z>u^NM0OF^A^(yjgs$FM#y*M7N7JW;s*GXC6 zpTRt>(hy-qo3=$z%R=Il67 zU&F7etuS%XB&aFusalOjZ5k|Z%|(@GT~GrKRhJi&waPE+p`-MN6MIYpmpkw^%T1#a zhhpIVQ{&WiEy$Gr8}>}TM+ew5ZVv-&5MA``qab1WoH55bAaIbfeKUdA?=&ZnqtcCM zAjS%QT<;p+WbyNK_~!8{W;xoVWcKZn^mPNpZ%<2XKQ`rLDem-`!Jf`G3NUt&kP1py zf@g}-eQTr&139j)+rQb~X_Z{feG)}`y=jhFkDhBwzKKppJg16kxU?TXebKbScVd7v z%DpdjZ9s~VIlG2wnI=-BlF3r3ZT0t}>o0L$pcS=Zo=yF*bJ_JUnKn|RiR57ZkNGoh zN!8w?;NK@BsMXuw`j?lSD6l4eqM3{%q2?ydR)>FWHt*ZF7OAR<1zFn5@IS_1vG70n zn`iFZzgW8V5a3(x+jl`%dtUyja*?#HNH||_Z&x1@fb(~CB)PgEgFHzdNL@WcW6KBz zj!UPj|2er_nv|UX*8`A2OQR*x3X*7yxim&eT2V<(MiMQjghua6uHgPpfVZ!Ur(4MX V9}r2j|9cq#=xN{7s@8Of{2yTISoHt^ literal 0 HcmV?d00001 diff --git a/samples/android/0-base/res/values/strings.xml b/samples/android/0-base/res/values/strings.xml new file mode 100644 index 0000000000..772538e141 --- /dev/null +++ b/samples/android/0-base/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Sample 0: base + diff --git a/samples/android/0-base/src/org/opencv/samples/Sample0Base.java b/samples/android/0-base/src/org/opencv/samples/Sample0Base.java new file mode 100644 index 0000000000..48bd49f4b1 --- /dev/null +++ b/samples/android/0-base/src/org/opencv/samples/Sample0Base.java @@ -0,0 +1,44 @@ +package org.opencv.samples; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.Window; + +public class Sample0Base extends Activity { + private static final String TAG = "Sample0Base::Activity"; + + public static final int view_mode_rgba = 0; + public static final int view_mode_gray = 1; + + private MenuItem item_preview_rgba; + private MenuItem item_preview_gray; + + public int view_mode; + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); + setContentView( new Sample0View(this) ); + view_mode = view_mode_rgba; + } + + public boolean onCreateOptionsMenu(Menu menu) { + item_preview_rgba = menu.add("Preview RGBA"); + item_preview_gray = menu.add("Preview GRAY"); + return true; + } + + public boolean onOptionsItemSelected (MenuItem item) { + Log.i(TAG, "Menu Item selected " + item); + if (item == item_preview_rgba) + view_mode = view_mode_rgba; + else if (item == item_preview_gray) + view_mode = view_mode_gray; + return true; + } +} diff --git a/samples/android/0-base/src/org/opencv/samples/Sample0View.java b/samples/android/0-base/src/org/opencv/samples/Sample0View.java new file mode 100644 index 0000000000..436cdb957e --- /dev/null +++ b/samples/android/0-base/src/org/opencv/samples/Sample0View.java @@ -0,0 +1,137 @@ +package org.opencv.samples; + +import java.util.List; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.hardware.Camera; +import android.hardware.Camera.PreviewCallback; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +class Sample0View extends SurfaceView implements SurfaceHolder.Callback, Runnable{ + private static final String TAG = "Sample0Base::View"; + + private Camera camera; + private SurfaceHolder holder; + private int frame_width; + private int frame_height; + private byte[] frame; + + private boolean mThreadRun; + + + public Sample0View(Context context) { + super(context); + holder = getHolder(); + holder.addCallback(this); + } + + + public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { + if ( camera != null) { + Camera.Parameters params = camera.getParameters(); + List sizes = params.getSupportedPreviewSizes(); + frame_width = width; + frame_height = height; + + //selecting optimal camera preview size + { + double minDiff = Double.MAX_VALUE; + for (Camera.Size size : sizes) { + if (Math.abs(size.height - height) < minDiff) { + frame_width = size.width; + frame_height = size.height; + minDiff = Math.abs(size.height - height); + } + } + } + params.setPreviewSize(frame_width, frame_height); + camera.setParameters(params); + camera.startPreview(); + } + } + + public void surfaceCreated(SurfaceHolder holder) { + camera = Camera.open(); + camera.setPreviewCallback( + new PreviewCallback() { + public void onPreviewFrame(byte[] data, Camera camera) { + synchronized(Sample0View.this) + { + frame = data; + Sample0View.this.notify(); + } + } + } + ); + (new Thread(this)).start(); + } + + public void surfaceDestroyed(SurfaceHolder holder) { + mThreadRun = false; + if(camera != null) { + camera.stopPreview(); + camera.setPreviewCallback(null); + camera.release(); + camera = null; + } + } + + public void run() { + mThreadRun = true; + Log.i(TAG, "Starting thread"); + while(mThreadRun) { + byte[] data = null; + synchronized(this) + { + try { + this.wait(); + data = frame; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + Canvas canvas = holder.lockCanvas(); + + int frameSize = frame_width*frame_height; + int[] rgba = new int[frameSize]; + + Sample0Base a = (Sample0Base)getContext(); + int view_mode = a.view_mode; + if(view_mode == Sample0Base.view_mode_gray) { + for(int i = 0; i < frameSize; i++) { + int y = (0xff & ((int)data[i])); + rgba[i] = 0xff000000 + (y << 16) + (y << 8) + y; + } + } + else if (view_mode == Sample0Base.view_mode_rgba) { + for(int i = 0; i < frame_height; i++) + for(int j = 0; j < frame_width; j++) { + int y = (0xff & ((int)data[i*frame_width+j])); + int u = (0xff & ((int)data[frameSize + (i >> 1) * frame_width + (j & ~1) + 0])); + int v = (0xff & ((int)data[frameSize + (i >> 1) * frame_width + (j & ~1) + 1])); + if (y < 16) y = 16; + + int r = Math.round(1.164f * (y - 16) + 1.596f * (v - 128) ); + int g = Math.round(1.164f * (y - 16) - 0.813f * (v - 128) - 0.391f * (u - 128)); + int b = Math.round(1.164f * (y - 16) + 2.018f * (u - 128)); + + if (r < 0) r = 0; if (r > 255) r = 255; + if (g < 0) g = 0; if (g > 255) g = 255; + if (b < 0) b = 0; if (b > 255) b = 255; + + rgba[i*frame_width+j] = 0xff000000 + (b << 16) + (g << 8) + r; + } + } + + Bitmap bmp = Bitmap.createBitmap(frame_width, frame_height, Bitmap.Config.ARGB_8888); + bmp.setPixels(rgba, 0/*offset*/, frame_width /*stride*/, 0, 0, frame_width, frame_height); + + canvas.drawBitmap(bmp, (canvas.getWidth()-frame_width)/2, (canvas.getHeight()-frame_height)/2, null); + holder.unlockCanvasAndPost(canvas); + } + } +} \ No newline at end of file