Guest User

Untitled

a guest
Jun 17th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.04 KB | None | 0 0
  1. package path.to.pkg
  2.  
  3. import android.app
  4. import android.os
  5.  
  6. import android.content
  7. import android.hardware
  8. import android.view
  9. import android.hardware
  10. import android.graphics
  11. import android.provider
  12. import android.content.res
  13.  
  14. import java.io
  15. import java.util
  16.  
  17. import scala.collection
  18. import scala.math
  19.  
  20. import scala.actors
  21.  
  22.  
  23. object SupportFuncs
  24. {
  25. def YUV422toARGB9999(src: Array[Byte], dest: Array[Int], w: Int, h: Int)
  26. {
  27. 0 until h foreach {
  28. y=>
  29. {
  30. 0 until w foreach {
  31. x=>
  32. {
  33. val i = y * w
  34. val s = src(i).asInstanceOf[Int] & 0xff
  35. dest(i) = 0xff000000 | s << 16 | s << 8 | s
  36. }
  37. }
  38. }
  39. }
  40. }
  41. }
  42.  
  43.  
  44. class PictureCallback(prev: Preview, ctx: content.Context) extends hardware.Camera.PictureCallback
  45. {
  46. val SDROOT = "/sdcard/"
  47.  
  48. def onPictureTaken(data: Array[Byte], cam: hardware.Camera)
  49. {
  50. prev.log("Take Photo")
  51. try
  52. {
  53. val name = "photo_" + String.valueOf(util.Calendar.getInstance.getTimeInMillis) + ".jpg"
  54. this.saveDataToSD(data, name)
  55. }
  56. catch
  57. {
  58. case e =>
  59. {
  60. prev.log(e)
  61. prev.cameraRelease
  62. }
  63. }
  64. }
  65.  
  66.  
  67. def saveDataToSD(data: Array[Byte], name: String)
  68. {
  69. try
  70. {
  71. val out = new java.io.FileOutputStream(this.SDROOT + name)
  72. try
  73. {
  74. out.write(data)
  75.  
  76. }
  77. finally
  78. {
  79. out.close
  80. }
  81. }
  82. catch
  83. {
  84. case e =>
  85. {
  86. prev.log(e)
  87. prev.cameraRelease
  88. }
  89. }
  90. }
  91.  
  92.  
  93. def saveDataToURI(data: Array[Byte], name: String)
  94. {
  95. val resolver = ctx.getContentResolver
  96. val bmp = graphics.BitmapFactory.decodeByteArray(data, 0, data.length)
  97. val vals = new content.ContentValues
  98. vals.put(provider.MediaStore.MediaColumns.DISPLAY_NAME, name)
  99. vals.put(provider.MediaStore.Images.ImageColumns.DESCRIPTION, "taken with me!")
  100. vals.put(provider.MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
  101. val uri = resolver.insert(provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, vals)
  102. try
  103. {
  104. val out = resolver.openOutputStream(uri)
  105. bmp.compress(graphics.Bitmap.CompressFormat.JPEG, 90, out)
  106. out.close
  107. }
  108. catch
  109. {
  110. case e =>
  111. {
  112. prev.log(e)
  113. prev.cameraRelease
  114. }
  115. }
  116. }
  117.  
  118. def onPause
  119. {
  120. prev.cameraRelease
  121. }
  122.  
  123. def onResume
  124. {
  125. prev.cameraRelease
  126. }
  127. }
  128.  
  129.  
  130. class CameraPreview(val par: Preview) extends hardware.Camera.PreviewCallback
  131. {
  132. override def onPreviewFrame(data: Array[Byte], cam: hardware.Camera)
  133. {
  134. par.log("preview")
  135.  
  136. val parm = cam.getParameters
  137. val size = parm.getPreviewSize
  138.  
  139. par.setRawImage(data, size.width, size.height)
  140. }
  141. }
  142.  
  143.  
  144.  
  145. class Preview(val context: content.Context) extends view.SurfaceView(context)
  146. with view.SurfaceHolder.Callback
  147. with Runnable
  148. {
  149. val holder = this.getHolder
  150. var camera: hardware.Camera = null
  151.  
  152. var rawImage: Array[Byte] = null
  153. var rawImageInt: Array[Int] = null
  154. var rawImageSize: (Int, Int) = null
  155. var bitmap: graphics.Bitmap = null
  156. var thread: Thread = null
  157. var visible = false
  158.  
  159. private val paint = new graphics.Paint()
  160. paint.setColor(0xffffffff)
  161. paint.setTextSize(32)
  162. paint.setTextAlign(graphics.Paint.Align.LEFT)
  163. paint.setLinearText(true)
  164.  
  165. paint.setAntiAlias(true)
  166. paint.setStrokeWidth(2)
  167. paint.setStrokeCap(graphics.Paint.Cap.ROUND)
  168. paint.setStyle(graphics.Paint.Style.STROKE)
  169.  
  170.  
  171. private val TAG = "Camera"
  172.  
  173.  
  174. def log[T](out: T)
  175. {
  176. android.util.Log.v(this.TAG, out.toString)
  177. }
  178.  
  179. holder.addCallback(this)
  180.  
  181. // サーフェイスタイプ指定
  182. // SURFACE_TYPE_PUSH_BUFFERS だと lockCanvas できない
  183. // holder.setType(view.SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)
  184. holder.setType(view.SurfaceHolder.SURFACE_TYPE_NORMAL)
  185.  
  186. def surfaceCreated(holder: view.SurfaceHolder)
  187. {
  188. try
  189. {
  190. this.log("surfaceCreated")
  191. this.camera = hardware.Camera.open
  192.  
  193. // RGB_565 にしても RGB_565 では取れない
  194. // val parm = this.camera.getParameters
  195. // parm.setPreviewFormat(graphics.ImageFormat.RGB_565)
  196. // this.camera.setParameters(parm)
  197.  
  198. // SURFACE_TYPE_NORMAL なので setPreviewDisplay が使えない
  199. // this.camera.setPreviewDisplay(holder)
  200. this.camera.setPreviewCallback(new CameraPreview(this))
  201.  
  202. // 即 startPreview したら真っ暗だったので、ちょっと待ってから
  203. actors.Actor.actor{
  204. Thread.sleep(3000)
  205. this.camera.startPreview
  206. }
  207.  
  208. // 描画スレッド開始
  209. this.thread = new Thread(this)
  210. this.thread.start
  211. this.visible = true
  212. this.log("surfaceCreated finish")
  213. }
  214. catch
  215. {
  216. case e =>
  217. {
  218. this.log("************* Errpr *************")
  219. this.log(e)
  220. this.cameraRelease
  221. }
  222. }
  223. }
  224.  
  225.  
  226. def surfaceDestroyed(holder: view.SurfaceHolder)
  227. {
  228. this.camera.stopPreview
  229. this.cameraRelease
  230.  
  231. // 描画スレッド終了
  232. try
  233. {
  234. this.thread.stop
  235. }
  236. catch
  237. {
  238. case e => {}
  239. }
  240. this.thread = null
  241. this.visible = false
  242. }
  243.  
  244.  
  245. def cameraRelease()
  246. {
  247. if (this.camera != null)
  248. {
  249. this.camera.setPreviewCallback(null)
  250. this.camera.stopPreview
  251. this.camera.release
  252. this.camera = null
  253. }
  254. }
  255.  
  256.  
  257. def getOptimalPreviewSize(sizes: List[hardware.Camera#Size],
  258. w: Int, h: Int): hardware.Camera#Size =
  259. {
  260. val AS_TOL = 0.05
  261. val targetratio = w.asInstanceOf[Double] / h
  262. val targetheight = h
  263.  
  264. if (sizes == null)
  265. {
  266. return null
  267. }
  268.  
  269. val (optsize, mindiff) = sizes.foldLeft((null: hardware.Camera#Size, Double.MaxValue)) {
  270. (x, y) =>
  271. {
  272. val (optimalSize, minDiff) = x
  273. val ratio = y.width.asInstanceOf[Double] / y.height
  274. if (math.abs(ratio - targetratio) > AS_TOL)
  275. {
  276. x
  277. }
  278. else if (math.abs(y.height - targetheight) < minDiff)
  279. {
  280. (y, math.abs(y.height - targetheight))
  281. }
  282. else
  283. {
  284. x
  285. }
  286. }
  287. }
  288.  
  289. if (optsize == null)
  290. {
  291. val (osize, diff) = sizes.foldLeft((optsize, Double.MaxValue)) {
  292. (x, y) =>
  293. {
  294. val (optimalSize, minDiff) = x
  295. if (math.abs(y.height - targetheight) < minDiff)
  296. {
  297. (y, math.abs(y.height - targetheight))
  298. }
  299. else
  300. {
  301. x
  302. }
  303. }
  304. }
  305. osize
  306. }
  307. else
  308. {
  309. optsize
  310. }
  311. }
  312.  
  313.  
  314. def surfaceChanged(holder: view.SurfaceHolder, fmt: Int, w: Int, h: Int)
  315. {
  316. this.log("surfaceChanged")
  317. val parms = this.camera.getParameters
  318. val sizes = collection.JavaConversions.asIterable(parms.getSupportedPreviewSizes).toList
  319. val optsize = this.getOptimalPreviewSize(sizes, w, h)
  320.  
  321. parms.setPreviewSize(optsize.width, optsize.height)
  322.  
  323. this.camera.setParameters(parms)
  324. this.camera.startPreview
  325. this.log("surfaceChanged finish")
  326. }
  327.  
  328.  
  329. override def onTouchEvent(evt: view.MotionEvent): Boolean =
  330. {
  331. this.log("touch: " + evt.getAction.toString)
  332.  
  333. if (evt.getAction == view.MotionEvent.ACTION_DOWN)
  334. {
  335. this.log("takePhoto!")
  336.  
  337. actors.Actor.actor{
  338. this.camera.takePicture(null, null, new PictureCallback(this, context))
  339. }
  340.  
  341. actors.Actor.actor{
  342. Thread.sleep(3000)
  343. this.camera.startPreview
  344. }
  345. }
  346. this.log("touch finish")
  347.  
  348. true
  349. }
  350.  
  351.  
  352. def setRawImage(data: Array[Byte], width: Int, height: Int)
  353. {
  354. this.rawImage = data
  355. this.rawImageSize = (width, height)
  356.  
  357. if (this.rawImageInt == null || this.rawImageInt.length != width * height)
  358. {
  359. this.rawImageInt = new Array[Int](width*height)
  360. this.bitmap = graphics.Bitmap.createBitmap(width, height, graphics.Bitmap.Config.ARGB_8888)
  361. }
  362.  
  363. if (this.rawImageInt != null)
  364. {
  365. }
  366.  
  367. }
  368.  
  369.  
  370. def run
  371. {
  372. while (true)
  373. {
  374.  
  375. if (!this.visible)
  376. {
  377. return
  378. }
  379.  
  380. try
  381. {
  382. this.doDraw
  383. }
  384. catch
  385. {
  386. case e => {}
  387. }
  388. // 遅いからいいや
  389. // Thread.sleep(33)
  390. }
  391. }
  392.  
  393.  
  394. def doDraw()
  395. {
  396. if (this.rawImage == null)
  397. {
  398. return
  399. }
  400.  
  401. val (w, h) = this.rawImageSize
  402.  
  403. val st = System.currentTimeMillis
  404.  
  405. // YUV422 -> ARGB8888
  406. // SupportFuncs.YUV422toARGB8888(this.rawImage, this.rawImageInt, w, h)
  407. Utils.YUV422toARGB8888(this.rawImage, this.rawImageInt, w, h)
  408. val yuv = System.currentTimeMillis
  409.  
  410. // Bitmap 生成
  411. this.bitmap.setPixels(this.rawImageInt, 0, w, 0, 0, w, h)
  412. // val bmp = graphics.Bitmap.createBitmap(this.rawImageInt, w, h, graphics.Bitmap.Config.ARGB_8888)
  413. val conv = System.currentTimeMillis
  414.  
  415. this.draw {
  416. cv=>{
  417. // 描画
  418. cv drawColor 0xff8833bb
  419. cv.drawBitmap(this.bitmap, 0, 0, this.paint)
  420. // cv.drawBitmap(this.rawImageInt, 0, w, 0, 0, w, h, true, this.paint)
  421. // cv.drawBitmap(bmp, 0, 0, this.paint)
  422.  
  423. val ed = System.currentTimeMillis
  424.  
  425. // デバッグ
  426. cv.drawText("Conv YUV " + (yuv-st).toString, 200, 100, this.paint)
  427. cv.drawText("Convert " + (conv-yuv).toString, 200, 150, this.paint)
  428. cv.drawText("Draw " + (ed-conv).toString, 200, 200, this.paint)
  429. cv.drawText("FPS " + (1000 / (ed-st)).toString, 200, 250, this.paint)
  430. }}
  431. }
  432.  
  433.  
  434. def draw(f: graphics.Canvas=>Unit)
  435. {
  436. val cv = this.holder.lockCanvas
  437.  
  438. try
  439. {
  440. cv.save
  441. f(cv)
  442. cv.restore
  443. }
  444. finally
  445. {
  446. this.holder unlockCanvasAndPost cv
  447. }
  448. }
  449. }
  450.  
  451.  
  452. class Camera extends app.Activity
  453. {
  454. var preview: Preview = null
  455.  
  456. override def onCreate(savedInstanceState: os.Bundle)
  457. {
  458. super.onCreate(savedInstanceState)
  459.  
  460. this.requestWindowFeature(view.Window.FEATURE_NO_TITLE)
  461.  
  462. this.preview = new Preview(this)
  463.  
  464. this.setContentView(this.preview)
  465. }
  466. }
Add Comment
Please, Sign In to add comment