使用HarmonyOS系统的Image组件加载部分网络图片时,图片会变成横屏展示,问题代码和截图如下,该如何解决?
Image('图片地址')
.objectFit(ImageFit.Contain)
.width('100%')
.backgroundColor(0x181818) 该问题的根本原因是图片里的Exif信息存在旋转90°的信息,HarmonyOS的Image组件会读取图片中的信息并旋转。如果不想旋转需要应用自行进行适配,目前可尝试以下方案适配:
// 根据获取到的EXIF方向信息,转换ImageRotateOrientation,使图片显示为正确的方向。
getOrientation(orientation: string): ImageRotateOrientation {
if (orientation == 'Top-right') {
return ImageRotateOrientation.UP_MIRRORED;
} else if (orientation == 'Bottom-right') {
return ImageRotateOrientation.DOWN;
} else if (orientation == 'Bottom-left') {
return ImageRotateOrientation.DOWN_MIRRORED;
} else if (orientation == 'Left-top') {
return ImageRotateOrientation.LEFT_MIRRORED;
} else if (orientation == 'Right-top') {
return ImageRotateOrientation.RIGHT;
} else if (orientation == 'Right-bottom') {
return ImageRotateOrientation.RIGHT_MIRRORED;
} else if (orientation == 'Left-bottom') {
return ImageRotateOrientation.LEFT;
} else if (orientation == 'Top-left') {
return ImageRotateOrientation.UP;
} else {
return ImageRotateOrientation.UP;
}
} requestImageUrl(url: string) {
http.createHttp().request(url,
{
expectDataType: http.HttpDataType.ARRAY_BUFFER
},
(error: BusinessError, data: http.HttpResponse) => {
if (error) {
console.error(`request image failed: url: ${url}, code: ${error.code}, message: ${error.message}`);
} else {
let imgData: ArrayBuffer = data.result as ArrayBuffer;
console.info(`request image success, size: ${imgData.byteLength}`);
let imgSource: image.ImageSource = image.createImageSource(imgData);
imgSource.createPixelMap().then((pixelMap: PixelMap) => {
imgSource.getImageProperty(image.PropertyKey.ORIENTATION).then((data: string) => {
console.info('image orientation data is', data);
this.rotateOrientation = this.getOrientation(data);
}).catch((error: BusinessError) => {
console.error(`Failed to get the value of the specified attribute key of the image, error.code ${error.code}, error.message ${error.message}`);
});
console.info('image createPixelMap success');
this.pixelMapImg1 = pixelMap;
imgSource.release();
}).catch(() => {
imgSource.release();
});
}
});
} 也可以通过downloadFile方法将图片下载到本地后,创建新PixelMap进行展示。
downloadImage() {
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
let tempPath = context.filesDir + '/' + new Date().getTime() + '.png';
try {
request.downloadFile(this.getUIContext().getHostContext(), {
url: this.imageUrl,
filePath: tempPath
}).then((downloadTask: request.DownloadTask) => {
downloadTask.on('complete', async () => {
let file = fileIo.openSync(tempPath, fileIo.OpenMode.READ_ONLY);
let imgSource: image.ImageSource = image.createImageSource(file.fd);
imgSource.createPixelMap().then((pixelMap: PixelMap) => {
imgSource.getImageProperty(image.PropertyKey.ORIENTATION).then((data: string) => {
this.rotateOrientation = this.getOrientation(data);
}).catch((error: BusinessError) => {
console.error(`Failed to get the value of the specified attribute key of the image, error.code ${error.code}, error.message ${error.message}`);
});
console.info('image createPixelMap success');
this.pixelMapImg2 = pixelMap;
imgSource.release();
}).catch(() => {
imgSource.release();
}).finally(() => {
fileIo.close(file);
});
});
});
} catch (error) {
console.error('download error', error);
}
} 完整代码如下:
import { http } from '@kit.NetworkKit';
import { BusinessError, request } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';
import { fileIo } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct CorrectDisplayOfImage {
@State rotateOrientation: ImageRotateOrientation = ImageRotateOrientation.UP;
@State pixelMapImg1: PixelMap | undefined = undefined;
@State pixelMapImg2: PixelMap | undefined = undefined;
imageUrl: string = ''; // 请填写一个具体的网络图片地址
// 根据获取到的EXIF方向信息,转换ImageRotateOrientation,使图片显示为正确的方向。
getOrientation(orientation: string): ImageRotateOrientation {
if (orientation == 'Top-right') {
return ImageRotateOrientation.UP_MIRRORED;
} else if (orientation == 'Bottom-right') {
return ImageRotateOrientation.DOWN;
} else if (orientation == 'Bottom-left') {
return ImageRotateOrientation.DOWN_MIRRORED;
} else if (orientation == 'Left-top') {
return ImageRotateOrientation.LEFT_MIRRORED;
} else if (orientation == 'Right-top') {
return ImageRotateOrientation.RIGHT;
} else if (orientation == 'Right-bottom') {
return ImageRotateOrientation.RIGHT_MIRRORED;
} else if (orientation == 'Left-bottom') {
return ImageRotateOrientation.LEFT;
} else if (orientation == 'Top-left') {
return ImageRotateOrientation.UP;
} else {
return ImageRotateOrientation.UP;
}
}
requestImageUrl(url: string) {
http.createHttp().request(url,
{
expectDataType: http.HttpDataType.ARRAY_BUFFER
},
(error: BusinessError, data: http.HttpResponse) => {
if (error) {
console.error(`request image failed: url: ${url}, code: ${error.code}, message: ${error.message}`);
} else {
let imgData: ArrayBuffer = data.result as ArrayBuffer;
console.info(`request image success, size: ${imgData.byteLength}`);
let imgSource: image.ImageSource = image.createImageSource(imgData);
imgSource.createPixelMap().then((pixelMap: PixelMap) => {
imgSource.getImageProperty(image.PropertyKey.ORIENTATION).then((data: string) => {
console.info('image orientation data is', data);
this.rotateOrientation = this.getOrientation(data);
}).catch((error: BusinessError) => {
console.error(`Failed to get the value of the specified attribute key of the image, error.code ${error.code}, error.message ${error.message}`);
});
console.info('image createPixelMap success');
this.pixelMapImg1 = pixelMap;
imgSource.release();
}).catch(() => {
imgSource.release();
});
}
});
}
downloadImage() {
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
let tempPath = context.filesDir + '/' + new Date().getTime() + '.png';
try {
request.downloadFile(this.getUIContext().getHostContext(), {
url: this.imageUrl,
filePath: tempPath
}).then((downloadTask: request.DownloadTask) => {
downloadTask.on('complete', async () => {
let file = fileIo.openSync(tempPath, fileIo.OpenMode.READ_ONLY);
let imgSource: image.ImageSource = image.createImageSource(file.fd);
imgSource.createPixelMap().then((pixelMap: PixelMap) => {
imgSource.getImageProperty(image.PropertyKey.ORIENTATION).then((data: string) => {
this.rotateOrientation = this.getOrientation(data);
}).catch((error: BusinessError) => {
console.error(`Failed to get the value of the specified attribute key of the image, error.code ${error.code}, error.message ${error.message}`);
});
console.info('image createPixelMap success');
this.pixelMapImg2 = pixelMap;
imgSource.release();
}).catch(() => {
imgSource.release();
}).finally(() => {
fileIo.close(file);
});
});
});
} catch (error) {
console.error('download error', error);
}
}
build() {
Column({ space: 20 }) {
Row() {
Text('直接加载网络图片');
Image(this.imageUrl)
.objectFit(ImageFit.Contain)
.height(200);
};
Row() {
Button('solution1')
.onClick(() => {
this.requestImageUrl(this.imageUrl); // 请填写一个具体的网络图片地址
});
Image(this.pixelMapImg1)
.objectFit(ImageFit.Contain)
.height(100)
.orientation(this.rotateOrientation)
};
Row() {
Button('solution2')
.onClick(() => {
this.downloadImage();
});
Image(this.pixelMapImg2)
.objectFit(ImageFit.Contain)
.height(100)
.orientation(this.rotateOrientation)
};
};
}
}