Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package path.to.pkg
- import android.app
- import android.os
- import android.content
- import android.hardware
- import android.view
- import android.hardware
- import android.graphics
- import android.provider
- import android.content.res
- import java.io
- import java.util
- import scala.collection
- import scala.math
- import scala.actors
- object SupportFuncs
- {
- def YUV422toARGB9999(src: Array[Byte], dest: Array[Int], w: Int, h: Int)
- {
- 0 until h foreach {
- y=>
- {
- 0 until w foreach {
- x=>
- {
- val i = y * w
- val s = src(i).asInstanceOf[Int] & 0xff
- dest(i) = 0xff000000 | s << 16 | s << 8 | s
- }
- }
- }
- }
- }
- }
- class PictureCallback(prev: Preview, ctx: content.Context) extends hardware.Camera.PictureCallback
- {
- val SDROOT = "/sdcard/"
- def onPictureTaken(data: Array[Byte], cam: hardware.Camera)
- {
- prev.log("Take Photo")
- try
- {
- val name = "photo_" + String.valueOf(util.Calendar.getInstance.getTimeInMillis) + ".jpg"
- this.saveDataToSD(data, name)
- }
- catch
- {
- case e =>
- {
- prev.log(e)
- prev.cameraRelease
- }
- }
- }
- def saveDataToSD(data: Array[Byte], name: String)
- {
- try
- {
- val out = new java.io.FileOutputStream(this.SDROOT + name)
- try
- {
- out.write(data)
- }
- finally
- {
- out.close
- }
- }
- catch
- {
- case e =>
- {
- prev.log(e)
- prev.cameraRelease
- }
- }
- }
- def saveDataToURI(data: Array[Byte], name: String)
- {
- val resolver = ctx.getContentResolver
- val bmp = graphics.BitmapFactory.decodeByteArray(data, 0, data.length)
- val vals = new content.ContentValues
- vals.put(provider.MediaStore.MediaColumns.DISPLAY_NAME, name)
- vals.put(provider.MediaStore.Images.ImageColumns.DESCRIPTION, "taken with me!")
- vals.put(provider.MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
- val uri = resolver.insert(provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, vals)
- try
- {
- val out = resolver.openOutputStream(uri)
- bmp.compress(graphics.Bitmap.CompressFormat.JPEG, 90, out)
- out.close
- }
- catch
- {
- case e =>
- {
- prev.log(e)
- prev.cameraRelease
- }
- }
- }
- def onPause
- {
- prev.cameraRelease
- }
- def onResume
- {
- prev.cameraRelease
- }
- }
- class CameraPreview(val par: Preview) extends hardware.Camera.PreviewCallback
- {
- override def onPreviewFrame(data: Array[Byte], cam: hardware.Camera)
- {
- par.log("preview")
- val parm = cam.getParameters
- val size = parm.getPreviewSize
- par.setRawImage(data, size.width, size.height)
- }
- }
- class Preview(val context: content.Context) extends view.SurfaceView(context)
- with view.SurfaceHolder.Callback
- with Runnable
- {
- val holder = this.getHolder
- var camera: hardware.Camera = null
- var rawImage: Array[Byte] = null
- var rawImageInt: Array[Int] = null
- var rawImageSize: (Int, Int) = null
- var bitmap: graphics.Bitmap = null
- var thread: Thread = null
- var visible = false
- private val paint = new graphics.Paint()
- paint.setColor(0xffffffff)
- paint.setTextSize(32)
- paint.setTextAlign(graphics.Paint.Align.LEFT)
- paint.setLinearText(true)
- paint.setAntiAlias(true)
- paint.setStrokeWidth(2)
- paint.setStrokeCap(graphics.Paint.Cap.ROUND)
- paint.setStyle(graphics.Paint.Style.STROKE)
- private val TAG = "Camera"
- def log[T](out: T)
- {
- android.util.Log.v(this.TAG, out.toString)
- }
- holder.addCallback(this)
- // サーフェイスタイプ指定
- // SURFACE_TYPE_PUSH_BUFFERS だと lockCanvas できない
- // holder.setType(view.SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)
- holder.setType(view.SurfaceHolder.SURFACE_TYPE_NORMAL)
- def surfaceCreated(holder: view.SurfaceHolder)
- {
- try
- {
- this.log("surfaceCreated")
- this.camera = hardware.Camera.open
- // RGB_565 にしても RGB_565 では取れない
- // val parm = this.camera.getParameters
- // parm.setPreviewFormat(graphics.ImageFormat.RGB_565)
- // this.camera.setParameters(parm)
- // SURFACE_TYPE_NORMAL なので setPreviewDisplay が使えない
- // this.camera.setPreviewDisplay(holder)
- this.camera.setPreviewCallback(new CameraPreview(this))
- // 即 startPreview したら真っ暗だったので、ちょっと待ってから
- actors.Actor.actor{
- Thread.sleep(3000)
- this.camera.startPreview
- }
- // 描画スレッド開始
- this.thread = new Thread(this)
- this.thread.start
- this.visible = true
- this.log("surfaceCreated finish")
- }
- catch
- {
- case e =>
- {
- this.log("************* Errpr *************")
- this.log(e)
- this.cameraRelease
- }
- }
- }
- def surfaceDestroyed(holder: view.SurfaceHolder)
- {
- this.camera.stopPreview
- this.cameraRelease
- // 描画スレッド終了
- try
- {
- this.thread.stop
- }
- catch
- {
- case e => {}
- }
- this.thread = null
- this.visible = false
- }
- def cameraRelease()
- {
- if (this.camera != null)
- {
- this.camera.setPreviewCallback(null)
- this.camera.stopPreview
- this.camera.release
- this.camera = null
- }
- }
- def getOptimalPreviewSize(sizes: List[hardware.Camera#Size],
- w: Int, h: Int): hardware.Camera#Size =
- {
- val AS_TOL = 0.05
- val targetratio = w.asInstanceOf[Double] / h
- val targetheight = h
- if (sizes == null)
- {
- return null
- }
- val (optsize, mindiff) = sizes.foldLeft((null: hardware.Camera#Size, Double.MaxValue)) {
- (x, y) =>
- {
- val (optimalSize, minDiff) = x
- val ratio = y.width.asInstanceOf[Double] / y.height
- if (math.abs(ratio - targetratio) > AS_TOL)
- {
- x
- }
- else if (math.abs(y.height - targetheight) < minDiff)
- {
- (y, math.abs(y.height - targetheight))
- }
- else
- {
- x
- }
- }
- }
- if (optsize == null)
- {
- val (osize, diff) = sizes.foldLeft((optsize, Double.MaxValue)) {
- (x, y) =>
- {
- val (optimalSize, minDiff) = x
- if (math.abs(y.height - targetheight) < minDiff)
- {
- (y, math.abs(y.height - targetheight))
- }
- else
- {
- x
- }
- }
- }
- osize
- }
- else
- {
- optsize
- }
- }
- def surfaceChanged(holder: view.SurfaceHolder, fmt: Int, w: Int, h: Int)
- {
- this.log("surfaceChanged")
- val parms = this.camera.getParameters
- val sizes = collection.JavaConversions.asIterable(parms.getSupportedPreviewSizes).toList
- val optsize = this.getOptimalPreviewSize(sizes, w, h)
- parms.setPreviewSize(optsize.width, optsize.height)
- this.camera.setParameters(parms)
- this.camera.startPreview
- this.log("surfaceChanged finish")
- }
- override def onTouchEvent(evt: view.MotionEvent): Boolean =
- {
- this.log("touch: " + evt.getAction.toString)
- if (evt.getAction == view.MotionEvent.ACTION_DOWN)
- {
- this.log("takePhoto!")
- actors.Actor.actor{
- this.camera.takePicture(null, null, new PictureCallback(this, context))
- }
- actors.Actor.actor{
- Thread.sleep(3000)
- this.camera.startPreview
- }
- }
- this.log("touch finish")
- true
- }
- def setRawImage(data: Array[Byte], width: Int, height: Int)
- {
- this.rawImage = data
- this.rawImageSize = (width, height)
- if (this.rawImageInt == null || this.rawImageInt.length != width * height)
- {
- this.rawImageInt = new Array[Int](width*height)
- this.bitmap = graphics.Bitmap.createBitmap(width, height, graphics.Bitmap.Config.ARGB_8888)
- }
- if (this.rawImageInt != null)
- {
- }
- }
- def run
- {
- while (true)
- {
- if (!this.visible)
- {
- return
- }
- try
- {
- this.doDraw
- }
- catch
- {
- case e => {}
- }
- // 遅いからいいや
- // Thread.sleep(33)
- }
- }
- def doDraw()
- {
- if (this.rawImage == null)
- {
- return
- }
- val (w, h) = this.rawImageSize
- val st = System.currentTimeMillis
- // YUV422 -> ARGB8888
- // SupportFuncs.YUV422toARGB8888(this.rawImage, this.rawImageInt, w, h)
- Utils.YUV422toARGB8888(this.rawImage, this.rawImageInt, w, h)
- val yuv = System.currentTimeMillis
- // Bitmap 生成
- this.bitmap.setPixels(this.rawImageInt, 0, w, 0, 0, w, h)
- // val bmp = graphics.Bitmap.createBitmap(this.rawImageInt, w, h, graphics.Bitmap.Config.ARGB_8888)
- val conv = System.currentTimeMillis
- this.draw {
- cv=>{
- // 描画
- cv drawColor 0xff8833bb
- cv.drawBitmap(this.bitmap, 0, 0, this.paint)
- // cv.drawBitmap(this.rawImageInt, 0, w, 0, 0, w, h, true, this.paint)
- // cv.drawBitmap(bmp, 0, 0, this.paint)
- val ed = System.currentTimeMillis
- // デバッグ
- cv.drawText("Conv YUV " + (yuv-st).toString, 200, 100, this.paint)
- cv.drawText("Convert " + (conv-yuv).toString, 200, 150, this.paint)
- cv.drawText("Draw " + (ed-conv).toString, 200, 200, this.paint)
- cv.drawText("FPS " + (1000 / (ed-st)).toString, 200, 250, this.paint)
- }}
- }
- def draw(f: graphics.Canvas=>Unit)
- {
- val cv = this.holder.lockCanvas
- try
- {
- cv.save
- f(cv)
- cv.restore
- }
- finally
- {
- this.holder unlockCanvasAndPost cv
- }
- }
- }
- class Camera extends app.Activity
- {
- var preview: Preview = null
- override def onCreate(savedInstanceState: os.Bundle)
- {
- super.onCreate(savedInstanceState)
- this.requestWindowFeature(view.Window.FEATURE_NO_TITLE)
- this.preview = new Preview(this)
- this.setContentView(this.preview)
- }
- }
Add Comment
Please, Sign In to add comment