智能客服
你问我答,随时在线为你解决问题

























在HarmonyOS应用开发中,存在大量需要获取媒体文件元数据信息的场景,例如:
为满足不同场景需求,本文介绍三种高效获取媒体文件信息的方案。
// 通过uri获取媒体文件信息
async uriGetAssets(uri: string) {
try {
const context = this.getUIContext().getHostContext();
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
// 配置查询条件,使用PhotoViewPicker选择图片返回的uri进行查询
predicates.equalTo('uri', uri);
let fetchOption: photoAccessHelper.FetchOptions = {
fetchColumns: [photoAccessHelper.PhotoKeys.WIDTH, photoAccessHelper.PhotoKeys.HEIGHT,
photoAccessHelper.PhotoKeys.TITLE, photoAccessHelper.PhotoKeys.DURATION],
predicates: predicates
};
let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> =
await phAccessHelper.getAssets(fetchOption);
// 得到uri对应的PhotoAsset对象,读取文件的部分信息
const asset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
let infoAsset = [asset.displayName, asset.uri, asset.photoType, asset.get(photoAccessHelper.PhotoKeys.WIDTH),
asset.get(photoAccessHelper.PhotoKeys.HEIGHT), asset.get(photoAccessHelper.PhotoKeys.TITLE)];
let infoAll = '';
for (let index = 0; index < this.ImageInfoalltitle.length; index++) {
const element = this.ImageInfoalltitle[index] + ':' + infoAsset[index] + '\n';
infoAll = infoAll + element;
}
this.ImageInfoAll.push(infoAll);
// 获取缩略图
asset.getThumbnail((err, pixelMap) => {
if (err == undefined) {
console.info(`getThumbnail successful ${JSON.stringify(pixelMap)}`);
} else {
console.error(`getThumbnail fail ${err}`);
}
});
} catch (error) {
console.error(`uriGetAssets failed with err: ${JSON.stringify(error)}`);
}
} // 获取沙箱图片基本信息
async getImageInfo() {
await this.photoPick();
let filePath: string = this.filePath;
console.info('filePath', filePath);
let imageSource = image.createImageSource(filePath);
let imageInfo = imageSource.getImageInfoSync(0);
this.ImageInfo = JSON.stringify(imageInfo);
if (imageInfo == undefined) {
console.error('Failed to obtain the image information.');
} else {
console.info('Succeeded in obtaining the image information.', this.ImageInfo);
}
} getImageProperties仅支持JPEG、PNG、HEIF、WEBP和DNG(不同硬件设备支持情况不同)文件,且需要包含Exif信息。WEBP和DNG在API23以上工程中支持。
// 获取沙箱图片Exif信息,此处以获取经纬度为例
async getImagePropertyKeyInfo() {
await this.photoPick();
let filePath: string = this.filePath;
console.info('filePath', filePath);
let imageSource = image.createImageSource(filePath);
await imageSource.getImageProperties([image.PropertyKey.GPS_LATITUDE, image.PropertyKey.GPS_LONGITUDE])
.then((data) => {
console.info('Succeeded in getting the value of the specified attribute key of the image.',
JSON.stringify(data));
this.ImageInfo2 = JSON.stringify(data);
}).catch((error: BusinessError) => {
this.ImageInfo2 = '';
console.error('Failed to get the value of the specified attribute key of the image.', error);
});
} 完整示例代码如下:
import { BusinessError } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import fs from '@ohos.file.fs';
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { dataSharePredicates } from '@kit.ArkData';
let uris: Array<string> = [];
const CAMERA_PERMISSION: Permissions = 'ohos.permission.MEDIA_LOCATION';
async function requestPermissions(permissions: Array<Permissions>, context: common.UIAbilityContext): Promise<void> {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
try {
await atManager.requestPermissionsFromUser(context, permissions);
} catch (err) {
console.error(`failed to request permissions from user, error is ${err}`);
}
}
@Entry
@Component
struct GetImageInfo {
@State ImageInfo: string = '点击后获取图片信息';
@State ImageInfo2: string = '点击后获取图片信息';
ImageInfoalltitle: Array<string> =
['displayName', 'uri', 'photoType', 'WIDTH', 'HEIGHT', 'TITLE'];
@State ImageInfoAll: Array<string | number | boolean> = [];
@State filePath: string = '';
aboutToAppear(): void {
// 拉起弹窗请求用户授权
requestPermissions([CAMERA_PERMISSION], this.getUIContext().getHostContext() as common.UIAbilityContext);
}
// 从相册选择图片,将图片复制到沙箱
async photoPick() {
let file1: fs.File | null = null;
let file2: fs.File | null = null;
try {
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
// 从相册选择图片并复制到沙箱
if (canIUse('SystemCapability.FileManagement.PhotoAccessHelper.Core')) {
let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
PhotoSelectOptions.maxSelectNumber = 1;
let photoPicker = new photoAccessHelper.PhotoViewPicker();
await photoPicker.select(PhotoSelectOptions)
.then(async (PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => {
let file1 = fs.openSync(PhotoSelectResult.photoUris[0]);
const dateStr = (new Date().getTime()).toString();
// 临时文件目录
let newPath = context.cacheDir + `/${dateStr + file1.name}`;
fs.copyFileSync(file1.fd, newPath);
let file2 = fs.openSync(newPath, fs.OpenMode.READ_WRITE);
console.info(`file fd ==> ${file2.fd} | file path ==> ${file2.path}`);
this.filePath = file2.path;
})
.catch((err: BusinessError) => {
console.error('PhotoViewPicker.select failed with err: ', err);
});
} else {
// Fallback for unsupported SystemCapability
}
} catch (error) {
let err: BusinessError = error as BusinessError;
console.error('PhotoViewPicker failed with err: ', err);
} finally {
if (file2 && file1) {
fs.closeSync(file1);
fs.closeSync(file2);
}
}
}
// 获取沙箱图片基本信息
async getImageInfo() {
await this.photoPick();
let filePath: string = this.filePath;
console.info('filePath', filePath);
let imageSource = image.createImageSource(filePath);
let imageInfo = imageSource.getImageInfoSync(0);
this.ImageInfo = JSON.stringify(imageInfo);
if (imageInfo == undefined) {
console.error('Failed to obtain the image information.');
} else {
console.info('Succeeded in obtaining the image information.', this.ImageInfo);
}
}
// 获取沙箱图片Exif信息,此处以获取经纬度为例
async getImagePropertyKeyInfo() {
await this.photoPick();
let filePath: string = this.filePath;
console.info('filePath', filePath);
let imageSource = image.createImageSource(filePath);
await imageSource.getImageProperties([image.PropertyKey.GPS_LATITUDE, image.PropertyKey.GPS_LONGITUDE])
.then((data) => {
console.info('Succeeded in getting the value of the specified attribute key of the image.',
JSON.stringify(data));
this.ImageInfo2 = JSON.stringify(data);
}).catch((error: BusinessError) => {
this.ImageInfo2 = '';
console.error('Failed to get the value of the specified attribute key of the image.', error);
});
}
// 拉起相册图片,获取图片PhotoSelectResult.photoUris
async photoPickerGetUri() {
try {
let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
PhotoSelectOptions.maxSelectNumber = 5;
let photoPicker = new photoAccessHelper.PhotoViewPicker();
photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => {
console.info(`PhotoViewPicker.select successfully, PhotoSelectResult uri: ${JSON.stringify(PhotoSelectResult)}`);
uris = PhotoSelectResult.photoUris;
this.ImageInfoAll = [];
// 通过uri获取媒体文件信息
for (let index = 0; index < uris.length; index++) {
this.uriGetAssets(uris[index]);
}
}).catch((err: BusinessError) => {
console.error(`PhotoViewPicker.select failed with err: ${JSON.stringify(err)}`);
});
} catch (error) {
let err: BusinessError = error as BusinessError;
console.error(`PhotoViewPicker failed with err: ${JSON.stringify(err)}`);
}
}
// 通过uri获取媒体文件信息
async uriGetAssets(uri: string) {
try {
const context = this.getUIContext().getHostContext();
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
// 配置查询条件,使用PhotoViewPicker选择图片返回的uri进行查询
predicates.equalTo('uri', uri);
let fetchOption: photoAccessHelper.FetchOptions = {
fetchColumns: [photoAccessHelper.PhotoKeys.WIDTH, photoAccessHelper.PhotoKeys.HEIGHT,
photoAccessHelper.PhotoKeys.TITLE, photoAccessHelper.PhotoKeys.DURATION],
predicates: predicates
};
let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> =
await phAccessHelper.getAssets(fetchOption);
// 得到uri对应的PhotoAsset对象,读取文件的部分信息
const asset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
let infoAsset = [asset.displayName, asset.uri, asset.photoType, asset.get(photoAccessHelper.PhotoKeys.WIDTH),
asset.get(photoAccessHelper.PhotoKeys.HEIGHT), asset.get(photoAccessHelper.PhotoKeys.TITLE)];
let infoAll = '';
for (let index = 0; index < this.ImageInfoalltitle.length; index++) {
const element = this.ImageInfoalltitle[index] + ':' + infoAsset[index] + '\n';
infoAll = infoAll + element;
}
this.ImageInfoAll.push(infoAll);
// 获取缩略图
asset.getThumbnail((err, pixelMap) => {
if (err == undefined) {
console.info(`getThumbnail successful ${JSON.stringify(pixelMap)}`);
} else {
console.error(`getThumbnail fail ${err}`);
}
});
} catch (error) {
console.error(`uriGetAssets failed with err: ${JSON.stringify(error)}`);
}
}
build() {
Column({ space: 10 }) {
Column({ space: 10 }) {
Text('获取沙箱路径图片基础信息')
.fontSize(18)
.fontWeight(600);
Button('获取')
.onClick(() => {
this.getImageInfo();
});
Column() {
Text(this.ImageInfo);
}
.width('90%')
.padding(10)
.backgroundColor('#f0f1f4')
.borderRadius(8);
};
Column({ space: 10 }) {
Text('获取沙箱路径图片exif信息')
.fontSize(18)
.fontWeight(600);
Row() {
Button('获取图片EXIF信息')
.onClick(() => {
this.getImagePropertyKeyInfo();
});
};
Column() {
Text(this.ImageInfo2);
}
.width('90%')
.padding(10)
.backgroundColor('#f0f1f4')
.borderRadius(8);
};
Column({ space: 10 }) {
Text('通过相册图片uri获取图片基础信息')
.fontSize(18)
.fontWeight(600);
Button('获取')
.onClick(() => {
this.photoPickerGetUri();
});
if (this.ImageInfoAll[0]!) {
Scroll() {
Column() {
ForEach(this.ImageInfoAll, (item: string | number | boolean) => {
Text(`${item}`);
}, (item: string, index: number) => index + item);
}
.width('90%')
.padding(10)
.backgroundColor('#f0f1f4')
.borderRadius(8);
}
.constraintSize({ maxHeight: 160 });
} else {
Column() {
Text('点击后获取图片信息');
}
.width('90%')
.padding(10)
.backgroundColor('#f0f1f4')
.borderRadius(8);
}
};
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center);
};
} 运行效果:

Q:使用getPropertyKey获取照片拍照时间的格式是否可以自定义?
A:不可以,年月日之间的分隔符是使用冒号,如“YY:MM:DD HH:mm:ss”或“YY:MM:DD”。
Q:如何获取图片的位置信息?
A:可以通过getImageProperty接口选择属性参数image.PropertyKey.GPS_LATITUDE和image.PropertyKey.GPS_LONGITUDE来获取图片的经纬度信息。
Q:如何获得图库图片的创建时间与拍摄时间。
A:getImageProperty可以获得图片EXIF属性的值,但是图片本身必须包含EXIF信息。如果保存到本地图库的图片不包含EXIF属性,无法获得EXIF属性值。
参考正文中场景一,在FetchOptions的fetchColumns参数中设置检索条件,添加图片创建时间PhotoKeys.DATE_ADDED_MS和图片拍摄时间PhotoKeys.DATE_TAKEN_MS。设置检索条件并获得图片/视频资源PhotoAsset后,通过get接口获得对应的参数值。
Q:如何获取图片的ISO感光度和曝光时间。
A:使用接口getImageProperty,ISO感光度用ISO_SPEED_RATINGS获取。曝光时间用EXPOSURE_TIME获取。具体可获取信息参考PropertyKey。
Q:用photoAccessHelper.getAssets获取相册文件uri之后,如何用imageSource获取文件全部EXIF信息。
A:系统目前仅支持对部分EXIF信息的查看和修改。HarmonyOS出于对用户隐私安全保护,对图片EXIF中的信息做了去隐私化处理,例如图片拍摄时间、地址位置信息等。如果开发者需要获取被隐藏的EXIF信息(如地理位置信息等),需要单独申请ohos.permission.MEDIA_LOCATION等权限。申请方式请参考声明权限>向用户申请授权。
Q:关于图片处理的方法image.createImageSource(uri)的参数,目前只支持应用的沙箱路径吗?使用PhotoViewPicker获取的图片uri,image.createImageSource(uri)方法会返回undefined。
A:image.createImageSource(uri)的参数uri当前仅支持应用沙箱路径。可参考接口文档image.createImageSource。
Q:选择图片后获取的缩略图大小和原图相同,如何定义缩略图尺寸。
A:PhotoAsset.getThumbnail(size)方法中size参数可为空,此时默认大小为256*256,如果需要自行调整缩略图大小,可手动设置size大小。
Q:调用phAccessHelper.getAssets方法根据指定获取资源时,抛出14000011错误码。
A:使用phAccessHelper.getAssets根据指定uri获取资源时,该方式是获取媒体库图片和视频资源,uri必须为媒体文件uri,不能传沙箱路径。
Q:如果获取EXIF信息时,获取的属性值不是图片存在的,是否会报错?
A:由于获取的属性图片不存在,会抛出异常:'Failed to get the value of the specified attribute key of the image.'。
Q:通过PhotoViewPicker选择图片后,读取已选择uri对应的图片宽高信息失败,抛出14000014错误码。
A:如果要获取宽高,需要指定FetchOptions。对于照片,如果该参数为空,默认查询'uri'、'media_type'、'subtype'和'display_name',其他的参数并不包含,需要加上,参考文档:FetchOptions。
Q:imageSource.getImageInfo()方法返回的宽高相反是什么原因。
A:通过文档如何获取图片的旋转角度信息判断图片是否存在旋转角度,若存在旋转角度属性图像查看器会根据旋转角度进行处理,因此屏幕图片展示宽高信息与图片实际宽高不一致。
智能客服
你问我答,随时在线为你解决问题
合作咨询
我们的专家服务团队将竭诚为您提供专业的合作咨询服务
解决方案
精准高效的一站式服务支持,助力开发者商业成功