当前位置: 代码迷 >> 综合 >> Android P 分析 HAL3 图片信息 exif
  详细解决方案

Android P 分析 HAL3 图片信息 exif

热度:61   发布时间:2023-12-29 09:16:58.0

jpeg Exif file format Marker APP1 简介

jpeg Exif file format Marker APP1 分析

Android P 分析 HAL3 JpegNode 生成图片流程

 

我的设备 MTK cpu  , Android P

在相册中查看手机拍摄的照片详情, 图片的相关信息: 制造商、日期、曝光时间、焦距、光圈值、GPS等信息。

那么拍摄照片的过程中是如何生成照片详情信息的呢?

照片中的信息保存的格式是 EXIF 。关于 Jpeg EIXF 的知识参考 jpeg Exif file format Marker APP1 简介 。

在分析 JpegNode 拍照pipeline 时,找到了 Jpeg EXIF 的代码。在这里简要分析。

 

代码位置:

vendor\mediatek\proprietary\hardware\mtkcam\utils\exif\v3\StdExif.cpp

vendor\mediatek\proprietary\hardware\mtkcam\include\mtkcam\utils\exif\IBaseCamExif.h -> ExifParams

 

初始化函数如下:

 初始化 ExifParams 的值。

MBOOL
StdExif::
init(ExifParams const&   rExifParams,MBOOL const         enableDbgExif
)
{mExifParam = rExifParams;MY_LOGI("mpExifParam(%p) ImageSize(%dx%d) FNumber(%d/10) FocalLegth(%d/1000) AWBMode(%d) Strobe(%d) AEMeterMode(%d) AEExpBias(%d)",&mExifParam, mExifParam.u4ImageWidth, mExifParam.u4ImageHeight, mExifParam.u4FNumber, mExifParam.u4FocalLength,mExifParam.u4AWBMode, mExifParam.u4FlashLightTimeus, mExifParam.u4AEMeterMode, mExifParam.i4AEExpBias);MY_LOGI("CapExposureTime(%d) AEISOSpeed(%d) LightSource(%d) ExpProgram(%d) SceneCapType(%d) Orientation(%d) ZoomRatio(%d) Facing(%d) ICC(%d)",mExifParam.u4CapExposureTime, mExifParam.u4AEISOSpeed, mExifParam.u4LightSource, mExifParam.u4ExpProgram,mExifParam.u4SceneCapType, mExifParam.u4Orientation, mExifParam.u4ZoomRatio, mExifParam.u4Facing, mExifParam.u4ICCIdx);MY_LOGI("GPS(%d), Altitude(%d), Latitude(%s), Longitude(%s), TimeStamp(%s), ProcessingMethod(%s)",mExifParam.u4GpsIsOn, mExifParam.u4GPSAltitude, mExifParam.uGPSLatitude,mExifParam.uGPSLongitude, mExifParam.uGPSTimeStamp, mExifParam.uGPSProcessingMethod);// DebugExif: reset debug informationmDbgInfo.clear();mMapModuleID.clear();//// Exif UtilitismpBaseExif = new ExifUtils();if ( !(mpBaseExif->init(mExifParam.u4GpsIsOn)) ){MY_LOGE("mpBaseExif->init() fail");return MFALSE;}//mpDebugIdMap = new ExifIdMap();//mbEnableDbgExif = enableDbgExif;mApp1Size       = mpBaseExif->exifApp1SizeGet();mDbgAppnSize    = isEnableDbgExif() ? (APPN_SIZE*APPN_COUNT) : 0;mICCIdx =  mExifParam.u4ICCIdx ; // sRGBmICCIdx = ::property_get_int32("jpeg.exif.icc.profile", mExifParam.u4ICCIdx);mICCSize = mICCIdx==EXIF_ICC_PROFILE_SRGB ? sizeof(icc_profile_srgb)/sizeof(int8_t) :(mICCIdx==EXIF_ICC_PROFILE_DCI_P3 ? sizeof(icc_profile_display_p3)/sizeof(int8_t) : 0) ;MY_LOGD_IF(mLogLevel, "ICCIdx %d ICCSize %zu", mICCIdx, mICCSize);//if ( ! getDebugExif() ) {MY_LOGE("bad getDebugExif()");return MFALSE;}//if  ( ! getBufInfo_cam() ) {MY_LOGE("bad getBufInfo_cam()");return MFALSE;}//return  MTRUE;
}

ExifParams 结构体

struct ExifParams {MUINT32     u4ImageWidth;       // Image widthMUINT32     u4ImageHeight;      // Image height//MUINT32     u4FNumber;          // Format: F2.8 = 28MUINT32     u4FocalLength;      // Format: FL 3.5 = 350MUINT32     u4FocalLength35mm;  // Format: FL35mm 28 = 28MUINT32     u4AWBMode;          // White balance modeMUINT32     u4LightSource;      // Light Source modeMUINT32     u4ExpProgram;       // Exposure ProgramMUINT32     u4SceneCapType;     // Scene Capture TypeMUINT32     u4FlashLightTimeus; // Strobe on/offMUINT32     u4AEMeterMode;      // Exposure metering modeMINT32      i4AEExpBias;        // Exposure index*10MUINT32     u4CapExposureTime;  //MUINT32     u4AEISOSpeed;       // AE ISO value//MUINT32     u4GpsIsOn;MUINT32     u4GPSAltitude;MUINT8      uGPSLatitude[32];MUINT8      uGPSLongitude[32];MUINT8      uGPSTimeStamp[32];MUINT8      uGPSProcessingMethod[64];   //(values of "GPS", "CELLID", "WLAN" or "MANUAL" by the EXIF spec.)//MUINT32     u4Orientation;      // 0, 90, 180, 270MUINT32     u4ZoomRatio;        // Digital zoom ratio (x100) For example, 100, 114, and 132 refer to 1.00, 1.14, and 1.32 respectively.//MUINT32     u4Facing;           // 1: front camera, 0: not frontMUINT32     u4ICCIdx;//
public:         Operations.ExifParams()  { ::memset(this, 0, sizeof(ExifParams)); }};

 

生成 EXIF 格式流

void
StdExif::
updateStdExif(exifAPP1Info_s* exifApp1Info)
{/*********************************************************************************GPS**********************************************************************************/
.../*********************************************************************************common**********************************************************************************/
.../*********************************************************************************3A**********************************************************************************/
.../*********************************************************************************update customized exif**********************************************************************************/
.../*********************************************************************************MISC**********************************************************************************/// [flashPixVer]memcpy(exifApp1Info->strFlashPixVer, "0100 ", 5);// [exposure mode]exifApp1Info->exposureMode = 0;  // 0 means Auto exposure}

 

JPEGNode 调用 StdExif 的 make 方法

如下代码,第一步调用  updateStdExif(&exifApp1Info);  生成 EXIF APP1

status_t
StdExif::
make(MUINTPTR const  outputExifBuf,size_t& rOutputExifSize
)
{int ret = 0;mpOutputExifBuf = outputExifBuf;// set 0 first for error returnrOutputExifSize = 0;MY_LOGI("out buffer(%#" PRIxPTR ")", getBufAddr());unsigned int u4OutputExifSize = 0;exifAPP1Info_s exifApp1Info;exifImageInfo_s exifImgInfo;//  (1) Fill exifApp1InfoupdateStdExif(&exifApp1Info);//  (2) Fill exifImgInfo::memset(&exifImgInfo, 0, sizeof(exifImageInfo_t));exifImgInfo.bufAddr     = getBufAddr();exifImgInfo.mainWidth   = mExifParam.u4ImageWidth;exifImgInfo.mainHeight  = mExifParam.u4ImageHeight;exifImgInfo.thumbSize   = getThumbnailSize();ret = mpBaseExif->exifApp1Make(&exifImgInfo, &exifApp1Info, &u4OutputExifSize);rOutputExifSize = (size_t)u4OutputExifSize;//  (4) Append App2int app2 = 2;unsigned int app2ReturnSize = 0;int size = mICCSize; // Data(n bytes)unsigned char *pAddr = (unsigned char*)getBufAddr()+ getStdExifSize() + getThumbnailSize();MY_LOGD_IF(mLogLevel,"offset %zu buf %p ", getBufAddr(), getStdExifSize() + getThumbnailSize() , pAddr);if(mICCIdx == EXIF_ICC_PROFILE_SRGB) {ret = mpBaseExif->exifAppnMake(app2, pAddr, (unsigned char*)&icc_profile_srgb, size, &app2ReturnSize, 0);}else if(mICCIdx == EXIF_ICC_PROFILE_DCI_P3) {ret = mpBaseExif->exifAppnMake(app2, pAddr, (unsigned char*)&icc_profile_display_p3, size, &app2ReturnSize, 0);}elseMY_LOGE("not support ICC profile %d", mICCIdx);// return app2ReturnSize is mICCSize + 2 +2 (Data(n bytes) + Data size(2 bytes) + Data tag(2 bytes))// (3) Append debug exifif ( isEnableDbgExif() ){updateDbgExif();}return (status_t)ret;
}

 

上述代码简要概述了相机拍照时 JpegNode 调用 StdExif 生成照片详细信息的流程。

如果需要加入自定义的照片信息,修改 StudExif.cpp 即可。

  相关解决方案