当前位置:首页 » 安卓系统 » androidyuvimage

androidyuvimage

发布时间: 2022-11-22 03:08:52

A. Android YuvImage 图片天生是横着

操作相机的Preview可通过以下三种方式添加回调接口:
Camera.setPreviewCallbackBuffer(PreviewCallback)
Camera.setOneShotPreviewCallback(PreviewCallback)
Camera.setPreviewCallback(PreviewCallback)
PreviewCallback接口里面只有一个回调方法:
void onPreviewFrame(byte[] data, Camera camera);

其中的byte[] data就是Preview的图像数据,格式为YuvImage,而这个图像天生是横着的,一般的旋转操作是:
YuvImage的byte[] –> Bitmap的byte[] –> 生成Bitmap –> 旋转Bitmap

原理 很复杂 直接上工具类

B. android预览图像为什么要转成yuvimage

发出光亮无比的光柱,历时40微秒,通过电流超过1万安培,这即第一次闪击.

C. 新手求教.有关onPreviewFrame未被调用的问题

● Camera.PreviewCallback:定义了onPreviewFrame(byte[] data, Camera camera) 方法,当存在预览帧(preview frame)时调用该方法。可以传入保存当前图像像素的字节数组。在Camera对象上,有3种不同的方式使用这个回调:
· setPreviewCallback(Camera.PreviewCallback):使用此方法注册一个Camera. PreviewCallback,这将确保在屏幕上显示一个新的预览帧时调用onPreviewFrame方法。传递到onPreviewFrame方法中的数据字节数组最有可能采用YUV格式。但是,Android 2.2是第一个包含了YUV格式解码器(YuvImage)的版本;在以前的版本中,必须手动完成解码。

· setOneShotPreviewCallback(Camera.PreviewCallback):利用Camera对象上的这个方法注册Camera.PreviewCallback,从而当下一幅预览图像可用时调用一次onPreviewFrame。同样,传递到onPreviewFrame方法的预览图像数据最有可能采用YUV格式。可以通过使用ImageFormat中的常量检查Camera. getParameters(). getPreviewFormat()返回的结果来确定这一点。

· setPreviewCallbackWithBuffer(Camera.PreviewCallback):在Android 2.2中引入了该方法,其与setPreviewCallback的工作方式相同,但要求指定一个字节数组作为缓冲区,用于预览图像数据。这是为了能够更好地管理处理预览图像时使用的内存。

● Camera.AutoFocusCallback:定义了onAutoFocus方法,当完成一个自动聚焦活动时调用它。通过传入此回调接口的一个实例,在调用Camera对象上的autoFocus方法时会触发自动聚焦。

● Camera.ErrorCallback:定义了onError方法,当发生一个Camera错误时调用它。有两个常量可用于与传入的错误代码进行比较:CAMERA_ERROR_UNKNOWN和CAMERA_ERROR_SERVER_DIED。

● Camera.OnZoomChangeListener:定义了onZoomChange方法,当正在进行或完成“平滑缩放”(慢慢缩小或放大)时调用它。在Android 2.2 (API Level 8)中引入了这个类和方法。

Camera.ShutterCallback:定义了onShutter方法,当捕获图像时立刻调用它

D. 请问android如何使用BitmapFactory.decodeStream解析很多张图片数据

是不是你第一张图结束了解析到一些不是第二张图的东东或者你少解析了第二张图的完整流。我之前就解析图片少一个字节图就出不来

E. Android开发 camera拍照无法获取Exit信息

private void data2file(byte[] w, String fileName) throws Exception {
FileOutputStream out = null;
try {

out = new FileOutputStream(fileName);
Bitmap bitmap = BitmapFactory.decodeByteArray(w, 0, w.length);
Matrix matrix=new Matrix();
matrix.postScale(1f, 1f);

//旋转图片
int deg = this.getWindowManager().getDefaultDisplay().getRotation();
if (deg == Surface.ROTATION_270) {
degree = 180;
matrix.postRotate(degree);
}

Bitmap dstbmp=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),
bitmap.getHeight(),matrix,true);

dstbmp.compress(CompressFormat.JPEG, 100, out);
//out.write(w);
out.flush();
out.close();
dstbmp.recycle();
bitmap.recycle();

} catch (Exception e) {
if (out != null)
out.close();
throw e;
}
}

生成图片地址后可以做这样处理,先旋转到合适的角度,再保存。

F. 如何在Android上快速显示yuv数据

最近在搞Android方面的视频处理开发,解码出来的都是YUV420格式的数据,如何在surface上高效显示出来,颇费了一点周折,现在总结一下。

思路1:在java中将Surface指针传递到jni层,lock之后就可以获得SurfaceInfo,进而取得要显示的surface格式、高度、宽度,在2.2/2.3版本,surface的Format一般都是RGB565格式,只用做一个颜色空间的转换,scaler就可以将yuv数据显示出来。
颜色空间转换和Scaler算是比较耗时的操作了。如何提高效率,scaler最好能交给android的底层函数去做,如果有gpu的,底层函数直接会利用gpu,效率非常高,又不占用cpu资源。

思路2:
参考framework中的AwesomePlayer,里面利用AwesomeLocalRenderer/AwesomeRemoteRenderer来实现解码出来的数据显示,这个效率应该非常高,但是平台的关联性会增加很多。
调用接口比较简单,
首先创建一个render,
mVideoRenderer = new AwesomeRemoteRenderer(
mClient.interface()->createRenderer(
mISurface, component,
(OMX_COLOR_FORMATTYPE)format,
decodedWidth, decodedHeight,
mVideoWidth, mVideoHeight,
rotationDegrees));
直接调用render函数就可以显示了。
virtual void render(MediaBuffer *buffer) {
void *id;
if (buffer->meta_data()->findPointer(kKeyBufferID, &id)) {
mTarget->render((IOMX::buffer_id)id);
}
}

其它的参数都很容易获得,关键是buffer_id 怎么获得?OMXCodec.cpp中有相关的可以参考。
实际的效果在我的S510E上跑,效率非常高,几乎不占用主控cpu资源,很可能都交给dsp和gpu去搞了。

思路3:
参考 camera的方式。由于在第2步已经取得了非常好的效果,笔者没有做深入研究。

G. 安卓开发,Camera的PreviewCallBack获取的byte[]怎么转为Bitmap

byte[]bb=newbyte[1024];

Bitmapbit=BitmapFactory.decodeByteArray(bb,0,bb.length);

H. 新手求教.有关onPreviewFrame未被调用的问题

在写一个简单的通过onPreviewFrame获取摄像头当前预览的图像再发送出去的程序。
但是运行的时候发现完全就没有调用这个函数。
用debug逐步调试的时候发现走到
camera.setPreviewCallback(MainActivity.this);这句就直接跳到设置变量的Camera camera;这句话然后就没有了。。。完全没有调用onPreviewFrame这个函数
代码

Java code?
package com.example.testfordraw;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import javax.security.auth.callback.Callback;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity implements SurfaceHolder.Callback,Camera.PreviewCallback{
private Camera camera;
public static ByteArrayOutputStream outputstream = null;
private SurfaceView msurfaceview;
private Button buttonstart;
private Button buttonstop;
private MediaRecorder recorder;
private SurfaceHolder surfaceholder;
private File savefile;
private File SDfile;
private String savepath;
private File recfile;
private int Width = 320;
private int Height = 240;
private boolean isRecording = false ;
private boolean istrans = false ;
private int videoformat=0;
private int VideoQuality=85;
private float VideoWidthRatio=1;
private float VideoHeightRatio=1;
private String username= "wh";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.activity_main);
msurfaceview = (SurfaceView) findViewById(R.id.mysurfaceview);
buttonstart = (Button) findViewById(R.id.start);
SDfile = Environment.getExternalStorageDirectory();
savepath = SDfile.getAbsolutePath()+File.separator+"mvideo"+File.separator;
savefile = new File(savepath);
buttonstart.setText("start");
buttonstart.setOnClickListener(new buttonstartlistener());
if (!savefile.exists())
{
savefile.mkdirs();
}
}
class buttonstartlistener implements OnClickListener{

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(istrans==false)
{
//record();
istrans = true;
camera.setPreviewCallback(MainActivity.this);
}else{
//Stoprecording();
istrans =false;
}
if(istrans == false)
{
buttonstart.setText("start");
}else{
buttonstart.setText("stop");
}
}
}
public void Stoprecording() {
if(recorder!= null){
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
isRecording = false ;
}
try{
camera.reconnect();
}catch(IOException e ){
Toast.makeText(this, "reconect fail", 0).show();
e.printStackTrace();
}
}
public void record()
{
try{

camera.unlock();
isRecording = true ;
recorder = new MediaRecorder();
recfile = File.createTempFile("Video",".3gp",savefile);
recorder.setCamera(camera);
recorder.reset();
recorder.setCamera(camera);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setOutputFile(recfile.getAbsolutePath());
recorder.setVideoSize(320,480);
recorder.setVideoFrameRate(20);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setPreviewDisplay(surfaceholder.getSurface());
recorder.prepare();
recorder.start();
}catch(IOException e){
e.printStackTrace();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// TODO Auto-generated method stub
if(istrans == false){
return;
}
if(data!=null)
{
try{
YuvImage image = new YuvImage(data, videoformat, Width, Height, null);
if(image!=null){
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
Rect rect = new Rect(0,0,(int)(VideoWidthRatio*Width),(int)(VideoHeightRatio*Height));
image.compressToJpeg(rect, VideoQuality, outstream);
outputstream = outstream;
outstream.flush();
}
}catch(Exception e){}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
if(camera != null){
return;
}
camera.stopPreview();
camera.setPreviewCallback(MainActivity.this);

Camera.Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
Width = size.width;
Height = size.height;
videoformat = parameters.getPreviewFormat();
camera.startPreview();
// TODO Auto-generated method stub

}

@Override
protected void onStart() {
// TODO Auto-generated method stub
surfaceholder = msurfaceview.getHolder();
surfaceholder.addCallback(this);
surfaceholder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
VideoWidthRatio=VideoWidthRatio/100f;
VideoHeightRatio=VideoHeightRatio/100f;
super.onStart();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
try{
camera.setPreviewDisplay(surfaceholder);
}catch (IOException e){
e.printStackTrace();
}
camera.startPreview();
Camera.Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
Width = size.width;
Height = size.height;
videoformat = parameters.getPreviewFormat();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(camera !=null){
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
camera = null;
}
}
}

I. android可否在NDK部分直接采集yuv图像

android是不可以在NDK部分直接采集yuv图像的,采集图像要用电脑中的扫描仪。
扫描仪是文字和图片输入的主要设备,相当于电脑的眼睛,能够通过光电器件把光信号转换为电信号,把电信号通过模数转换器转化为数字信号传输到电脑中,把大量的文字、图片信息输入到电脑中。
扫描仪的关键器件是电荷耦合器,采用三棱镜分色光学系统,以三棱镜来分离自然光为红、绿、蓝三原色来扫描图形。
用平板式扫描仪把文件扫描到电脑上的时候,要把文字和图片固定在一个玻璃窗口中,扫描头在文字或图片下移动,接受来自文字或图片的反射光,这些反射线由一个镜面系统进行反射,通过凸透镜把光聚焦到光敏二极管上面,把光变成电流,最后再转换成数字信息存储在电脑中,它能一次扫描,读入一整页的文字或图片。
扫描仪的性能指标包括:光学分辨率、色彩位数、扫描速度和幅面大小。光学分辨率也叫水平分辨率,单位为像素/英寸或点/英寸。色彩位数是扫描仪对图片色彩的分辨能力。

J. 视频流怎么转换成图片

//byte[] data
YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
这个YuvImage是Android里的,不知道Java有木有这个。不过这个转换是转换成Jepg。
不是很符合你的要求,不过应该对你的研究有点帮助吧。

热点内容
arm编译添加驱动 发布:2024-05-21 02:02:28 浏览:475
安卓设置页面是怎么 发布:2024-05-21 01:32:51 浏览:520
学生成绩管理系统数据库设计 发布:2024-05-21 01:14:41 浏览:42
我的世界什么指令直接出现服务器 发布:2024-05-21 01:10:00 浏览:397
星等算法 发布:2024-05-21 00:53:06 浏览:509
李兴华的java视频 发布:2024-05-21 00:49:55 浏览:605
数据库4种索引类型 发布:2024-05-21 00:47:29 浏览:241
给服务器添加另一个ip 发布:2024-05-21 00:40:37 浏览:821
搭建ftp服务器出现微软蓝屏 发布:2024-05-21 00:35:18 浏览:369
ftp怎么加照片 发布:2024-05-21 00:14:37 浏览:623