當前位置:首頁 » 安卓系統 » 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。
不是很符合你的要求,不過應該對你的研究有點幫助吧。

熱點內容
外網用戶訪問內網 發布:2025-03-07 07:10:28 瀏覽:63
sql2008express下載 發布:2025-03-07 07:07:53 瀏覽:545
sqlserver存儲過程輸出 發布:2025-03-07 06:58:39 瀏覽:841
免費雲伺服器搭建上網工具 發布:2025-03-07 06:51:15 瀏覽:930
sqlserver2008語言 發布:2025-03-07 06:48:50 瀏覽:865
國際版mc如何進伺服器 發布:2025-03-07 06:48:49 瀏覽:219
安卓語音記錄如何清除 發布:2025-03-07 06:36:03 瀏覽:412
Java運行腳本優化 發布:2025-03-07 06:29:38 瀏覽:979
wrt編譯軟路由添加驅動 發布:2025-03-07 06:28:38 瀏覽:973
Ajaxphpjquery分頁 發布:2025-03-07 06:24:25 瀏覽:838