我想在没有之前的情况下从相机中获取图像。
这是我的 mainactivity.java :
public class MainActivity extends AppCompatActivity {
private Camera mCamera;
private byte[] mVideoSource;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
mCamera = Camera.open();
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
int j =2;
public void onPreviewFrame(final byte[] data, final Camera camera) {
// Process the contents of byte for whatever you need
j++;
}
});
mCamera.setDisplayOrientation(0);
// Finds a suitable resolution.
Size size= new Size(640,480);
// Set-up camera size and video format. YCbCr_420_SP
// should be the default on Android anyway.
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(size.getWidth(), size.getHeight());
parameters.setPreviewFormat(PixelFormat.YCbCr_420_SP);
mCamera.setParameters(parameters);
PixelFormat pixelFormat = new PixelFormat();
PixelFormat.getPixelFormatInfo(mCamera.getParameters()
.getPreviewFormat(), pixelFormat);
int sourceSize = size.getWidth() * size.getHeight()
* pixelFormat.bitsPerPixel / 8;
mVideoSource = new byte[sourceSize];
// Starts receiving pictures from the camera.
mCamera.addCallbackBuffer(mVideoSource);
mCamera.startPreview();
}
我不明白为什么程序永远不会通过PreviewCallback。在变量中,预览回调函数似乎已经很好地改变了。
事实上我只想从相机中抓取图像。
编辑: 以下是我给你的链接所做的修改。
public class AGLSurfaceView extends GLSurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {
private final AGLRenderer mRenderer;
Camera mCamera;
public AGLSurfaceView(Context context) {
super(context);
// Create an OpenGL ES 2.0 context.
setEGLContextClientVersion(2);
// Set the Renderer for drawing on the GLSurfaceView
mRenderer = new AGLRenderer(context);
setRenderer(mRenderer);
// Render the view only when there is a change in the drawing data
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
private final float TOUCH_SCALE_FACTOR = 180.0f / 3200;
private float mPreviousX;
private float mPreviousY;
@Override
public boolean onTouchEvent(MotionEvent e) {
// MotionEvent reports input details from the touch screen
// and other input controls. In this case, you are only
// interested in events where the touch position changed.
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_MOVE:
float dx = x - mPreviousX;
float dy = y - mPreviousY;
// reverse direction of rotation above the mid-line
if (y > getHeight() / 2) {
dx = dx * -1 ;
}
// reverse direction of rotation to left of the mid-line
if (x < getWidth() / 2) {
dy = dy * -1 ;
}
mRenderer.setAngle(mRenderer.getAngleX() + dy * TOUCH_SCALE_FACTOR,
mRenderer.getAngleY() + dx * TOUCH_SCALE_FACTOR); // = 180.0f / 320
requestRender();
}
mPreviousX = x;
mPreviousY = y;
return true;
}
public void setBackground(Bitmap b)
{
mRenderer.setBackground(b);
}
public void setAngle(float X,float Y,float Z)
{
mRenderer.setAngle(X,Y,Z);
requestRender();
}
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(640, 480);
mCamera.setParameters(p);
try {
mCamera.setPreviewDisplay(getHolder());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
mCamera.setPreviewCallback(this);
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
int i = 1;
}
和渲染
public class AGLRenderer implements GLSurfaceView.Renderer {
private static final String TAG = "AGLRenderer";
private BackgroundTexture mBackgroundTexture;
private SquareTexture mSquareTexture;
private Square mSquare;
// mMVPMatrix is an abbreviation for "Model View Projection Matrix"
private final float[] mMVPMatrix = new float[16];
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16];
private final float[] mRotationMatrix = new float[16];
private final float[] mRotationMatrixlX = new float[16];
private final float[] mRotationMatrixlY = new float[16];
private final float[] mRotationMatrixX = new float[16];
private final float[] mRotationMatrixY = new float[16];
private final float[] mRotationMatrixZ = new float[16];
private final float[] mRotationMatrix0 = new float[16];
float angleX ,angleY ,angleZ ;
private float mAngleX;
private float mAngleY;
Context localcontext;
public AGLRenderer(Context context) {
super();
localcontext = context;
}
public void setAngle(float X,float Y,float Z)
{
angleX = X;
angleY = Y;
angleZ = Z;
}
@Override
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
angleX = 0;
angleY = 0;
angleZ = 0;
// Set the background frame color
GLES20.glClearColor(1.0f, 0.1f, 0.0f, 1.0f);
mSquareTexture = new SquareTexture(localcontext);
mSquare = new Square();
mBackgroundTexture = new BackgroundTexture(localcontext);
mBackgroundTexture.loadTexture();
}
@Override
public void onDrawFrame(GL10 unused) {
float[] scratch = new float[16];
// Draw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// Set the camera position (View matrix)
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -10, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// Matrix.setRotateM(mRotationMatrix0, 0, angleX, 0, 1.0f, 0);
Matrix.setRotateM(mRotationMatrixX, 0, angleX, 0, 1,0);
Matrix.setRotateM(mRotationMatrixY, 0, angleY, 0, 0,1);
Matrix.setRotateM(mRotationMatrixZ, 0, angleZ, 1, 0,0);
// for(int j=0;j<4;j++)
// {
// for(int i=0;i<4;i++)
// {
// Log.d("tt"," "+(mRotationMatrix0[j*4+i]));
// }
// }
Matrix.multiplyMM(mRotationMatrix0, 0,mRotationMatrixY , 0, mRotationMatrixZ, 0);
Matrix.multiplyMM(mRotationMatrix0, 0,mRotationMatrix0 , 0, mRotationMatrixX, 0);
Matrix.multiplyMM(mRotationMatrix, 0,mRotationMatrix0 , 0, mViewMatrix , 0);
// Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mRotationMatrix, 0);
// Draw square
//mSquareTexture.draw(mMVPMatrix);
mSquare.draw(mMVPMatrix);
//mBackgroundTexture.draw();
}
@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
// Adjust the viewport based on geometry changes,
// such as screen rotation
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
// this projection matrix is applied to object coordinates
// in the onDrawFrame() method
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 50);
}
/**
* Utility method for compiling a OpenGL shader.
*
* <p><strong>Note:</strong> When developing shaders, use the checkGlError()
* method to debug shader coding errors.</p>
*
* @param type - Vertex or fragment shader type.
* @param shaderCode - String containing the shader code.
* @return - Returns an id for the shader.
*/
public static int loadShader(int type, String shaderCode){
// create a vertex shader type (GLES20.GL_VERTEX_SHADER)
// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// add the source code to the shader and compile it
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
/**
* Utility method for debugging OpenGL calls. Provide the name of the call
* just after making it:
*
* <pre>
* mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
* AGLRenderer.checkGlError("glGetUniformLocation");</pre>
*
* If the operation is not successful, the check throws an error.
*
* @param glOperation - Name of the OpenGL call to check.
*/
public static void checkGlError(String glOperation) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.e(TAG, glOperation + ": glError " + error);
throw new RuntimeException(glOperation + ": glError " + error);
}
}
/**
* Returns the rotation angle of the triangle shape (mTriangle).
*
* @return - A float representing the rotation angle.
*/
public float getAngleX() {
return mAngleX;
}
public float getAngleY() {
return mAngleY;
}
/**
* Sets the rotation angle of the triangle shape (mTriangle).
*/
public void setAngle(float angleX,float angleY) {
mAngleX = angleX;
mAngleY = angleY;
}
public void setBackground(Bitmap background)
{
mBackgroundTexture.loadTexture(background);
}
}
我在GLSurfaceView上预览了我的相机,但程序不再通过GLSurfaceView.Renderer的onSurfaceCreated,ondrawframe。怎么可能呢?
实际上我的目标是显示相机图像并能够在其上方绘制3d对象。
编辑:
我发现其他程序是我的主要活动:
public class MainActivity extends AppCompatActivity{
GLSurfaceView glView;
CameraView cameraView;
GLClearRenderer clearRenderer;
@Override
public void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
// When working with the camera, it's useful to stick to one orientation.
setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE );
// Next, we disable the application's title bar...
requestWindowFeature( Window.FEATURE_NO_TITLE );
// ...and the notification bar. That way, we can use the full screen.
getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN );
// Now let's create an OpenGL surface.
glView = new GLSurfaceView( this );
// To see the camera preview, the OpenGL surface has to be created translucently.
// See link above.
glView.setEGLConfigChooser( 8, 8, 8, 8, 16, 0 );
glView.getHolder().setFormat( PixelFormat.TRANSLUCENT );
// The renderer will be implemented in a separate class, GLView, which I'll show next.
clearRenderer = new GLClearRenderer();
glView.setRenderer( clearRenderer );
// Now set this as the main view.
setContentView( glView );
// Now also create a view which contains the camera preview...
cameraView = new CameraView( this );
// ...and add it, wrapping the full screen size.
addContentView( cameraView, new ActionBar.LayoutParams( ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT ) );
}
public class GLClearRenderer implements GLSurfaceView.Renderer {
private BackgroundTexture mBackgroundTexture;
private SquareTexture mSquareTexture;
private Square mSquare;
// mMVPMatrix is an abbreviation for "Model View Projection Matrix"
private final float[] mMVPMatrix = new float[16];
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16];
private final float[] mRotationMatrix = new float[16];
private final float[] mRotationMatrixlX = new float[16];
private final float[] mRotationMatrixlY = new float[16];
private final float[] mRotationMatrixX = new float[16];
private final float[] mRotationMatrixY = new float[16];
private final float[] mRotationMatrixZ = new float[16];
private final float[] mRotationMatrix0 = new float[16];
float angleX ,angleY ,angleZ ;
private float mAngleX;
private float mAngleY;
public void onDrawFrame( GL10 gl ) {
// This method is called per frame, as the name suggests.
// For demonstration purposes, I simply clear the screen with a random translucent gray.
float c = 1.0f / 256 * ( System.currentTimeMillis() % 256 );
GLES20.glClearColor( c, c, c, 0.5f );
GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT );
// Draw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// Set the camera position (View matrix)
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -10, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
// Draw square
mSquare.draw(mMVPMatrix); %%%%%%% NOT DISPLAY
}
public void onSurfaceChanged( GL10 gl, int width, int height ) {
// This is called whenever the dimensions of the surface have changed.
// We need to adapt this change for the GL viewport.
GLES20.glViewport( 0, 0, width, height );
float ratio = (float) width / height;
// this projection matrix is applied to object coordinates
// in the onDrawFrame() method
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 50);
}
public void onSurfaceCreated( GL10 gl, EGLConfig config ) {
// No need to do anything here.
angleX = 0;
angleY = 0;
angleZ = 0;
// Set the background frame color
//GLES20.glClearColor(1.0f, 0.1f, 0.0f, 1.0f);
mSquare = new Square(); %%%%%%% NOT DISPLAY
}
}
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private Camera camera;
public CameraView( Context context ) {
super( context );
// We're implementing the Callback interface and want to get notified
// about certain surface events.
getHolder().addCallback( this );
// We're changing the surface to a PUSH surface, meaning we're receiving
// all buffer data from another component - the camera, in this case.
getHolder().setType( SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS );
}
public void surfaceCreated( SurfaceHolder holder ) {
// Once the surface is created, simply open a handle to the camera hardware.
camera = Camera.open();
}
public void surfaceChanged( SurfaceHolder holder, int format, int width, int height ) {
// This method is called when the surface changes, e.g. when it's size is set.
// We use the opportunity to initialize the camera preview display dimensions.
Camera.Parameters p = camera.getParameters();
p.setPreviewSize( width, height );
//camera.setParameters( p );
// We also assign the preview display to this surface...
try {
camera.setPreviewDisplay( holder );
} catch( IOException e ) {
e.printStackTrace();
}
// ...and start previewing. From now on, the camera keeps pushing preview
// images to the surface.
camera.startPreview();
}
public void surfaceDestroyed( SurfaceHolder holder ) {
// Once the surface gets destroyed, we stop the preview mode and release
// the whole camera since we no longer need it.
camera.stopPreview();
camera.release();
camera = null;
}
}
}
屏幕闪烁有效,但我使用的方块不显示。我不明白为什么。
答案 0 :(得分:0)
查看此主题,了解如何创建预览类以在同一活动中显示相机预览 - https://developer.android.com/guide/topics/media/camera.html