Android Open Source - 3D-Compass Camera Useful






From Project

Back to project page 3D-Compass.

License

The source code is released under:

Apache License

If you think the Android project 3D-Compass listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package nz.gen.geek_central.Compass3D;
/*//from  ww w .  ja  va  2s  .c om
    Useful camera-related stuff.

    Copyright 2011, 2013 by Lawrence D'Oliveiro <ldo@geek-central.gen.nz>.

    Licensed under the Apache License, Version 2.0 (the "License"); you may not
    use this file except in compliance with the License. You may obtain a copy of
    the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    License for the specific language governing permissions and limitations under
    the License.
*/

import android.hardware.Camera;

public class CameraUseful
  {

    public static int NV21DataSize
      (
        int Width,
        int Height
      )
      /* returns the size of a data buffer to hold an NV21-encoded image
        of the specified dimensions. */
      {
        return
                Width * Height
            +
                ((Width + 1) / 2) * ((Height + 1) / 2) * 2;
      } /*NV21DataSize*/

    public static void DecodeNV21
      (
        int SrcWidth, /* dimensions of image before rotation */
        int SrcHeight,
        byte[] Data, /* length = NV21DataSize(SrcWidth, SrcHeight) */
        int Rotate, /* [0 .. 3], angle is 90 * Rotate clockwise */
        int Alpha, /* set as alpha for all decoded pixels */
        int[] Pixels /* length = Width * Height */
      )
      /* decodes NV21-encoded image data, which is the default camera preview image format. */
      {
        final int AlphaMask = Alpha << 24;
      /* Rotation involves accessing either the source or destination pixels in a
        non-sequential fashion. Since the source is smaller, I figure it's less
        cache-unfriendly to go jumping around that. */
        final int DstWidth = (Rotate & 1) != 0 ? SrcHeight : SrcWidth;
        final int DstHeight = (Rotate & 1) != 0 ? SrcWidth : SrcHeight;
        final boolean DecrementRow = Rotate > 1;
        final boolean DecrementCol = Rotate == 1 || Rotate == 2;
        final int LumaRowStride = (Rotate & 1) != 0 ? 1 : SrcWidth;
        final int LumaColStride = (Rotate & 1) != 0 ? SrcWidth : 1;
        final int ChromaRowStride = (Rotate & 1) != 0 ? 2 : SrcWidth;
        final int ChromaColStride = (Rotate & 1) != 0 ? SrcWidth : 2;
        int dst = 0;
        for (int row = DecrementRow ? DstHeight : 0;;)
          {
            if (row == (DecrementRow ? 0 : DstHeight))
                break;
            if (DecrementRow)
              {
                --row;
              } /*if*/
            for (int col = DecrementCol ? DstWidth : 0;;)
              {
                if (col == (DecrementCol ? 0 : DstWidth))
                    break;
                if (DecrementCol)
                  {
                    --col;
                  } /*if*/
                final int Y = 0xff & (int)Data[row * LumaRowStride + col * LumaColStride]; /* [0 .. 255] */
              /* U/V data follows entire luminance block, downsampled to half luminance
                resolution both horizontally and vertically */
              /* decoding follows algorithm shown at
                <http://www.mail-archive.com/android-developers@googlegroups.com/msg14558.html>,
                except it gets red and blue the wrong way round (decoding NV12 rather than NV21) */
              /* see also good overview of YUV-family formats at <http://wiki.videolan.org/YUV> */
                final int Cr =
                    (0xff & (int)Data[SrcHeight * SrcWidth + row / 2 * ChromaRowStride + col / 2 * ChromaColStride]) - 128;
                      /* [-128 .. +127] */
                final int Cb =
                    (0xff & (int)Data[SrcHeight * SrcWidth + row / 2 * ChromaRowStride + col / 2 * ChromaColStride + 1]) - 128;
                      /* [-128 .. +127] */
                Pixels[dst++] =
                  /* fixme: should I premultiply alpha? */
                        AlphaMask
                    |
                            Math.max
                              (
                                Math.min
                                  (
                                    (
                                            Y
                                        +
                                            Cr
                                        +
                                            (Cr >> 1)
                                        +
                                            (Cr >> 2)
                                        +
                                            (Cr >> 6)
                                    ),
                                    255
                                  ),
                                  0
                              )
                        <<
                            16 /* red */
                    |
                            Math.max
                              (
                                Math.min
                                  (
                                    (
                                            Y
                                        -
                                            (Cr >> 2)
                                        +
                                            (Cr >> 4)
                                        +
                                            (Cr >> 5)
                                        -
                                            (Cb >> 1)
                                        +
                                            (Cb >> 3)
                                        +
                                            (Cb >> 4)
                                        +
                                            (Cb >> 5)
                                    ),
                                    255
                                  ),
                                0
                              )
                        <<
                            8 /* green */
                    |
                        Math.max
                          (
                            Math.min
                              (
                                (
                                        Y
                                    +
                                        Cb
                                    +
                                        (Cb >> 2)
                                    +
                                        (Cb >> 3)
                                    +
                                        (Cb >> 5)
                                ),
                                255
                              ),
                            0
                          ); /* blue */
                if (!DecrementCol)
                  {
                    ++col;
                  } /*if*/
              } /*for*/
            if (!DecrementRow)
              {
                ++row;
              } /*if*/
          } /*for*/
      } /*DecodeNV21*/

    private static class API9Stuff
      /* stuff only available in API 9 or later. */
      {

        public Camera OpenCamera
          (
            int CameraID
          )
          {
            return
                Camera.open(CameraID);
          } /*OpenCamera*/

        public static Camera.CameraInfo GetCameraInfo
          (
            int CameraID
          )
          /* allocates and fills in a Camera.CameraInfo object for
            the specified camera. */
          {
            final Camera.CameraInfo Result = new Camera.CameraInfo();
            Camera.getCameraInfo(CameraID, Result);
            return
                Result;
          } /*GetCameraInfo*/

        public static int FirstCamera
          (
            boolean FrontFacing /* false for rear-facing */
          )
          /* returns the ID of the first camera with the specified Facing value
            in its CameraInfo. */
          {
            int Result = -1;
            for (int i = 0;;)
              {
                if (i == Camera.getNumberOfCameras())
                    break;
                if
                  (
                        GetCameraInfo(i).facing
                    ==
                        (FrontFacing ?
                            Camera.CameraInfo.CAMERA_FACING_FRONT
                        :
                            Camera.CameraInfo.CAMERA_FACING_BACK
                        )
                  )
                  {
                    Result = i;
                    break;
                  } /*if*/
                ++i;
              } /*for*/
            return
                Result;
          } /*FirstCamera*/

        public static int RightOrientation
          (
            android.app.Activity DisplayActivity,
            int CameraID
          )
          /* returns the value to pass to setDisplayOrientation for an instance
            of the specified camera so image will be right way up when
            displayed according to the screen orientation of DisplayActivity. */
          {
            final Camera.CameraInfo Info = GetCameraInfo(CameraID);
            final boolean FrontFacing = Info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT;
            final int Degrees =
                    (
                        Info.orientation
                    +
                            DisplayActivity.getWindowManager().getDefaultDisplay().getRotation()
                        *
                            90
                        *
                            (FrontFacing ? 1 : -1)
                    +
                        360 /* ensure non-negative for correct modulus */
                    )
                %
                    360;
            System.err.printf
              (
                "CameraUseful.RightOrientation camera %d frontfacing %s orientation %d display rotation %d, degrees %d return %d\n",
                CameraID,
                FrontFacing,
                Info.orientation,
                DisplayActivity.getWindowManager().getDefaultDisplay().getRotation(),
                Degrees,
                FrontFacing ? (360 - Degrees) % 360 : Degrees
              ); /* debug */
            return
                FrontFacing ?
                    (360 - Degrees) % 360
                :
                    Degrees;
          } /*RightOrientation*/

      } /*API9Stuff*/;
    private static API9Stuff API9;

    static
      {
        API9 = null; /* to begin with */
        try
          {
            final API9Stuff TheAPI9 = new API9Stuff();
          /* trying to do something API-9-specific in constructor doesn't seem to fail properly, try it here */
            final int i = TheAPI9.FirstCamera(false);
          /* OK, that succeeded... */
            API9 = TheAPI9;
          }
        catch (NoClassDefFoundError TooOld)
          {
          }
        catch (ExceptionInInitializerError TooOld)
          {
          }
        catch (NoSuchMethodError TooOld)
          {
          } /*catch*/
      } /*static*/

    public static boolean CanTellCameraPresent()
      /* does FirstCamera (below) actually return a meaningful result. */
      {
        return
            API9 != null;
      } /*CanTellCameraPresent*/

    public static Camera OpenCamera
      (
        int CameraID /* any non-negative value valid pre-API-9 */
      )
      {
        return
            API9 != null ?
                API9.OpenCamera(CameraID)
            : CameraID >= 0 ?
                Camera.open()
            :
                null;
      } /*OpenCamera*/

    public static Camera.CameraInfo GetCameraInfo
      (
        int CameraID
      )
      /* allocates and fills in a Camera.CameraInfo object for
        the specified camera. Returns null pre-API-9. */
      {
        return
            API9 != null ?
                API9.GetCameraInfo(CameraID)
            :
                null;
      } /*GetCameraInfo*/

    public static int FirstCamera
      (
        boolean FrontFacing /* false for rear-facing */
      )
      /* returns the ID of the first camera with the specified Facing value
        in its CameraInfo. Pre-API-9, I just assume there may be one rear-facing
        camera and no front-facing camera, but you can't tell for sure until
        you actually try to open the camera. */
      {
        return
            API9 != null ?
                API9.FirstCamera(FrontFacing)
            : FrontFacing ? /* camera IDs not meaningful pre-API 9, assume just one camera, only rear-facing */
                -1
            :
                0;
      } /*FirstCamera*/

    public static int RightOrientation
      (
        android.app.Activity DisplayActivity,
        int CameraID
      )
      /* returns the value to pass to setDisplayOrientation for an instance
        of the specified camera so image will be right way up when
        displayed according to the screen orientation of DisplayActivity. */
      {
        return
            API9 != null ?
                API9.RightOrientation(DisplayActivity, CameraID)
            :
                    (
                        DisplayActivity.getWindowManager().getDefaultDisplay().getRotation() * -90
                    +
                        90 /* or something */
                    +
                        360
                    )
                %
                    360;
      } /*RightOrientation*/

    public static android.graphics.Point GetSmallestPreviewSizeAtLeast
      (
        Camera TheCamera,
        int MinWidth,
        int MinHeight
      )
      /* returns smallest supported preview size which is of at least
        the given dimensions. */
      {
        Camera.Size BestSize = null;
        for
          (
            Camera.Size ThisSize : TheCamera.getParameters().getSupportedPreviewSizes()
          )
          {
            if (ThisSize.width >= MinWidth && ThisSize.height >= MinHeight)
              {
                if
                  (
                        BestSize == null
                    ||
                        BestSize.width > ThisSize.width
                    ||
                        BestSize.height > ThisSize.height
                  )
                  {
                    BestSize = ThisSize;
                  } /*if*/
              } /*if*/
          } /*for*/
        if (BestSize == null)
          {
          /* none big enough, pick first, which seems to be biggest */
            BestSize = TheCamera.getParameters().getSupportedPreviewSizes().get(0);
          } /*if*/
        return
            new android.graphics.Point(BestSize.width, BestSize.height);
      } /*GetSmallestPreviewSizeAtLeast*/

    public static android.graphics.Point GetLargestPreviewSizeAtMost
      (
        Camera TheCamera,
        int MaxWidth,
        int MaxHeight
      )
      /* returns largest supported preview size which is of at most
        the given dimensions. */
      {
        Camera.Size BestSize = null;
        for
          (
            Camera.Size ThisSize : TheCamera.getParameters().getSupportedPreviewSizes()
          )
          {
            if (ThisSize.width <= MaxWidth && ThisSize.height <= MaxHeight)
              {
                if
                  (
                        BestSize == null
                    ||
                        BestSize.width < ThisSize.width
                    ||
                        BestSize.height < ThisSize.height
                  )
                  {
                    BestSize = ThisSize;
                  } /*if*/
              } /*if*/
          } /*for*/
        if (BestSize == null)
          {
          /* none big enough, pick last, which seems to be smallest */
            final java.util.List<Camera.Size> PreviewSizes =
                TheCamera.getParameters().getSupportedPreviewSizes();
            BestSize = PreviewSizes.get(PreviewSizes.size() - 1);
          } /*if*/
        return
            new android.graphics.Point(BestSize.width, BestSize.height);
      } /*GetLargestPreviewSizeAtMost*/

  } /*CameraUseful*/




Java Source Code List

nz.gen.geek_central.Compass3D.CameraList.java
nz.gen.geek_central.Compass3D.CameraUseful.java
nz.gen.geek_central.Compass3D.Compass.java
nz.gen.geek_central.Compass3D.MainView.java
nz.gen.geek_central.Compass3D.Main.java
nz.gen.geek_central.GLUseful.BaseRenderer.java
nz.gen.geek_central.GLUseful.GLBitmapView.java
nz.gen.geek_central.GLUseful.GLTextureView.java
nz.gen.geek_central.GLUseful.GLUseful.java
nz.gen.geek_central.GLUseful.GeomBuilder.java
nz.gen.geek_central.GLUseful.Lathe.java
nz.gen.geek_central.GLUseful.Mat4f.java
nz.gen.geek_central.GLUseful.Vec3f.java