HarmonyOS 鸿蒙Next:【PixelMap】crop后,显示到Image控件中仍然未被截取
HarmonyOS 鸿蒙Next:【PixelMap】crop后,显示到Image控件中仍然未被截取 按照以下代码,点击添加照片按钮,期望显示一张被截取了一半的图片,但不管origin还是cropped,显示在Image中的都是完整而未被截取的图片。(后来试着多点几次添加同一张照片,有点时候能小概率(低于50%)显示两个Image均为截取后的图片)
<div class="highlight-div">
<div class="highlight-div-header">
<div class="handle-button theme-button">
<div class="handle-hover-tips">深色代码主题</div>
</div>
<div class="handle-button copy-button">
<div class="handle-hover-tips">复制</div>
</div>
</div>
<pre><code class="language-javascript hljs" data-highlighted="yes">
<span class="hljs-keyword">import</span> { photoAccessHelper } <span class="hljs-keyword">from</span> <span class="hljs-string">'@kit.MediaLibraryKit'</span>;
<span class="hljs-keyword">import</span> { fileIo, picker } <span class="hljs-keyword">from</span> <span class="hljs-string">'@kit.CoreFileKit'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">BusinessError</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@kit.BasicServicesKit'</span>;
<span class="hljs-keyword">import</span> { image } <span class="hljs-keyword">from</span> <span class="hljs-string">'@kit.ImageKit'</span>;
@<span class="hljs-title class_">Entry</span>
@<span class="hljs-title class_">Component</span>
struct <span class="hljs-title class_">CropPage</span> {
@<span class="hljs-title class_">State</span> <span class="hljs-attr">origin</span>: <span class="hljs-title class_">PixelMap</span> | <span class="hljs-literal">undefined</span> = <span class="hljs-literal">undefined</span>
@<span class="hljs-title class_">State</span> <span class="hljs-attr">cropped</span>: <span class="hljs-title class_">PixelMap</span> | <span class="hljs-literal">undefined</span> = <span class="hljs-literal">undefined</span>
private <span class="hljs-keyword">async</span> <span class="hljs-title function_">decodeImage</span>(<span class="hljs-params">uri: string</span>) {
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">let</span> file = fileIo.<span class="hljs-title function_">openSync</span>(uri, fileIo.<span class="hljs-property">OpenMode</span>.<span class="hljs-property">READ_ONLY</span>)
<span class="hljs-keyword">const</span> imageSourceApi = image.<span class="hljs-title function_">createImageSource</span>(file.<span class="hljs-property">fd</span>)
imageSourceApi.<span class="hljs-title function_">getImageInfo</span>(<span class="hljs-number">0</span>, <span class="hljs-function">(<span class="hljs-params">error: BusinessError, imageInfo</span>) =></span> {
<span class="hljs-keyword">if</span> (imageInfo ==
<span class="hljs-literal">undefined</span>) {
<span class="hljs-comment">//log.e(error)</span>
}
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`imageInfo: <span class="hljs-subst">${<span class="hljs-built_in">JSON</span>.stringify(imageInfo)}</span>`</span>)
})
<span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> imageSourceApi.<span class="hljs-title function_">createPixelMap</span>()
} <span class="hljs-keyword">catch</span> (error) {
<span class="hljs-comment">//log.e(error)</span>
<span class="hljs-keyword">return</span> <span class="hljs-literal">undefined</span>
}
}
<span class="hljs-title function_">build</span>(<span class="hljs-params"></span>) {
<span class="hljs-title class_">Column</span>() {
<span class="hljs-title class_">Button</span>(<span class="hljs-string">'添加照片'</span>).<span class="hljs-title function_">onClick</span>(<span class="hljs-keyword">async</span> () => {
<span class="hljs-keyword">let</span> uris = <span class="hljs-keyword">await</span> <span class="hljs-title function_">selectPhoto</span>({
<span class="hljs-title class_">MIMEType</span>: picker.<span class="hljs-property">PhotoViewMIMETypes</span>.<span class="hljs-property">IMAGE_TYPE</span>,
<span class="hljs-attr">maxSelectNumber</span>: <span class="hljs-number">1</span>,
<span class="hljs-attr">isPhotoTakingSupported</span>: <span class="hljs-literal">false</span>,
<span class="hljs-attr">recommendationOptions</span>: { <span class="hljs-attr">recommendationType</span>: photoAccessHelper.<span class="hljs-property">RecommendationType</span>.<span class="hljs-property">PROFILE_PICTURE</span>, }
})
<span class="hljs-keyword">if</span> (uris.<span class="hljs-property">length</span> == <span class="hljs-number">0</span>) {
<span class="hljs-keyword">return</span>
}
<span class="hljs-variable language_">this</span>.<span class="hljs-property">origin</span> = <span class="hljs-keyword">await</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">decodeImage</span>(uris[<span class="hljs-number">0</span>])
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">origin</span>) {
<span class="hljs-keyword">let</span> info = <span class="hljs-keyword">await</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">origin</span>.<span class="hljs-title function_">getImageInfo</span>()
<span class="hljs-variable language_">this</span>.<span class="hljs-property">origin</span>.<span class="hljs-title function_">crop</span>({ <span class="hljs-attr">x</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">size</span>: { <span class="hljs-attr">width</span>: info.<span class="hljs-property">size</span>.<span class="hljs-property">width</span>, <span class="hljs-attr">height</span>: info.<span class="hljs-property">size</span>.<span class="hljs-property">height</span> / <span class="hljs-number">2</span> } })
<span class="hljs-variable language_">this</span>.<span class="hljs-property">cropped</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">origin</span>
}
})
<span class="hljs-title class_">Image</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">origin</span>).<span class="hljs-title function_">width</span>(<span class="hljs-string">'100%'</span>).<span class="hljs-title function_">height</span>(<span class="hljs-string">'100%'</span>).<span class="hljs-title function_">layoutWeight</span>(<span class="hljs-number">1</span>).<span class="hljs-title function_">objectFit</span>(<span class="hljs-title class_">ImageFit</span>.<span class="hljs-property">Contain</span>)
<span class="hljs-title class_">Image</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">cropped</span>).<span class="hljs-title function_">width</span>(<span class="hljs-string">'100%'</span>).<span class="hljs-title function_">height</span>(<span class="hljs-string">'100%'</span>).<span class="hljs-title function_">layoutWeight</span>(<span class="hljs-number">1</span>).<span class="hljs-title function_">objectFit</span>(<span class="hljs-title class_">ImageFit</span>.<span class="hljs-property">Contain</span>)
}.<span class="hljs-title function_">width</span>(<span class="hljs-string">`100%`</span>)
}
}
<span class="hljs-keyword">const</span> <span class="hljs-attr">PHOTO_DEFAULT_SELECT_NUMBER</span>: number =
<span class="hljs-number">9</span>;
<span class="hljs-comment">//数量 </span>
<span class="hljs-comment">/**
* 通过选择模式拉起photoPicker界面,用户可以选择一个或多个图片/视频。
* <span class="hljs-doctag">@param</span> options * <span class="hljs-doctag">@returns</span>
**/</span>
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">selectPhoto</span>(<span class="hljs-params">options?: PhotoSelectOptions</span>): <span class="hljs-title class_">Promise</span><<span class="hljs-title class_">Array</span><string>> {
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">if</span> (!options) {
options = <span class="hljs-keyword">new</span> <span class="hljs-title class_">PhotoSelectOptions</span>();
}
<span class="hljs-keyword">if</span> (!options.<span class="hljs-property">MIMEType</span>) {
<span class="hljs-comment">//可选择的媒体文件类型,若无此参数,则默认为图片和视频类型。 </span>
options.<span class="hljs-property">MIMEType</span> = photoAccessHelper.<span class="hljs-property">PhotoViewMIMETypes</span>.<span class="hljs-property">IMAGE_TYPE</span>;
}
<span class="hljs-keyword">if</span> (!options.<span class="hljs-property">maxSelectNumber</span>) {
<span class="hljs-comment">//选择媒体文件数量的最大值,默认9 </span>
options.<span class="hljs-property">maxSelectNumber</span> = <span class="hljs-variable constant_">PHOTO_DEFAULT_SELECT_NUMBER</span>;
}
<span class="hljs-keyword">if</span> (options.<span class="hljs-property">isPhotoTakingSupported</span> == <span class="hljs-literal">undefined</span>) {
options.<span class="hljs-property">isPhotoTakingSupported</span> =
<span class="hljs-literal">true</span>;
<span class="hljs-comment">//支持拍照。 </span>
<span class="hljs-comment">// } </span>
<span class="hljs-keyword">if</span> (options.<span class="hljs-property">isEditSupported</span> == <span class="hljs-literal">undefined</span>) {
options.<span class="hljs-property">isEditSupported</span> =
<span class="hljs-literal">true</span>;
<span class="hljs-comment">//支持编辑照片。 </span>
<span class="hljs-comment">// } </span>
<span class="hljs-keyword">if</span> (options.<span class="hljs-property">isSearchSupported</span> == <span class="hljs-literal">undefined</span>) {
options.<span class="hljs-property">isSearchSupported</span> =
<span class="hljs-literal">true</span>;
<span class="hljs-comment">//支持编辑照片。 </span>
<span class="hljs-comment">// } </span>
<span class="hljs-keyword">let</span> <span class="hljs-attr">photoSelectOptions</span>: photoAccessHelper.<span class="hljs-property">PhotoSelectOptions</span> = {
<span class="hljs-title class_">MIMEType</span>: options.<span class="hljs-property">MIMEType</span>,
<span class="hljs-attr">maxSelectNumber</span>: options.<span class="hljs-property">maxSelectNumber</span>,
<span class="hljs-attr">isPhotoTakingSupported</span>: options.<span class="hljs-property">isPhotoTakingSupported</span>,
<span class="hljs-attr">isEditSupported</span>: options.<span class="hljs-property">isEditSupported</span>,
<span class="hljs-attr">isSearchSupported</span>: options.<span class="hljs-property">isSearchSupported</span>,
<span class="hljs-attr">recommendationOptions</span>: options.<span class="hljs-property">recommendationOptions</span>,
<span class="hljs-attr">preselectedUris</span>: options.<span class="hljs-property">preselectedUris</span>
}
<span class="hljs-keyword">let</span> photoPicker = <span class="hljs-keyword">new</span> photoAccessHelper.<span class="hljs-title class_">PhotoViewPicker</span>();
<span class="hljs-keyword">let</span> <span class="hljs-attr">photoSelectResult</span>: photoAccessHelper.<span class="hljs-property">PhotoSelectResult</span> = <span class="hljs-keyword">await</span> photoPicker.<span class="hljs-title function_">select</span>(photoSelectOptions)
<span class="hljs-keyword">if</span> (photoSelectResult && photoSelectResult.<span class="hljs-property">photoUris</span> && photoSelectResult.<span class="hljs-property">photoUris</span>.<span class="hljs-property">length</span> > <span class="hljs-number">0</span>) {
<span class="hljs-keyword">return</span> photoSelectResult.<span class="hljs-property">photoUris</span>
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">return</span> [];
}
}
<span class="hljs-keyword">catch</span>(err) {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(err)
<span class="hljs-keyword">return</span> [];
}
}
<span class="hljs-keyword">class</span> <span class="hljs-title class_">PhotoSelectOptions</span> {
<span class="hljs-title class_">MIMEType</span>?: photoAccessHelper.<span class="hljs-property">PhotoViewMIMETypes</span> =
photoAccessHelper.<span class="hljs-property">PhotoViewMIMETypes</span>.<span class="hljs-property">IMAGE_TYPE</span>;
<span class="hljs-comment">//可选择的媒体文件类型,若无此参数,则默认为图片和视频类型。 </span>
maxSelectNumber?: number = <span class="hljs-variable constant_">PHOTO_DEFAULT_SELECT_NUMBER</span>;
<span class="hljs-comment">//选择媒体文件数量的最大值(默认值为50,最大值为500)。 </span>
isPhotoTakingSupported?: boolean = <span class="hljs-literal">true</span>;
<span class="hljs-comment">//支持拍照。 </span>
isEditSupported?: boolean = <span class="hljs-literal">true</span>;
<span class="hljs-comment">//支持编辑照片。 </span>
isSearchSupported?: boolean = <span class="hljs-literal">true</span>;
<span class="hljs-comment">//支持搜索。 </span>
recommendationOptions?: photoAccessHelper.<span class="hljs-property">RecommendationOptions</span>;
<span class="hljs-comment">//支持照片推荐。 </span>
preselectedUris?: <span class="hljs-title class_">Array</span><string>;
<span class="hljs-comment">//预选择图片的uri数据。 </span>
<span class="hljs-comment">// }</span>
}
</code></pre>
更多关于HarmonyOS 鸿蒙Next:【PixelMap】crop后,显示到Image控件中仍然未被截取的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
修改后代码
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo, picker } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';
@Entry
@Component
struct Index {
@State origin: PixelMap | undefined = undefined
@State origin2: PixelMap | undefined = undefined
@State cropped: PixelMap | undefined = undefined
private uri:string = ''
private async decodeImage(uri: string) {
try {
let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY)
const imageSourceApi = image.createImageSource(file.fd)
imageSourceApi.getImageInfo(0, (error: BusinessError, imageInfo) => {
if (imageInfo == undefined) {
// log.e(error)
}
console.log(`imageInfo: ${JSON.stringify(imageInfo)}`)
})
return await imageSourceApi.createPixelMap()
} catch (error) {
// log.e(error)
return undefined
}
}
build() {
Column() {
Button('添加照片')
.onClick(async () => {
let uris = await selectPhoto({
MIMEType: picker.PhotoViewMIMETypes.IMAGE_TYPE,
maxSelectNumber: 1,
isPhotoTakingSupported: false,
recommendationOptions: {
recommendationType: photoAccessHelper.RecommendationType.PROFILE_PICTURE,
}
})
if (uris.length == 0) {
return
}
this.origin = await this.decodeImage(uris[0])
this.origin2 = await this.decodeImage(uris[0])
if (this.origin) {
let info = await this.origin.getImageInfo()
let region: image.Region = { x: 0, y: 0, size: { height: info.size.height / 2, width: info.size.width } };
if (this.origin2 != undefined) {
this.origin2.crop(region).then(async () => {
if (this.origin2 != undefined) {
let pixel = await copyPixelMap(this.origin2);
this.origin2.release();
this.origin2 = pixel;
console.info('Sucessed in setting crop.');
}
}).catch((err: BusinessError) => {
console.error('Failed to crop pixelmap.');
})
}
}
})
Image(this.origin)
.width('100%')
.height('100%')
.layoutWeight(1)
.objectFit(ImageFit.Contain)
Image(this.origin2)
.width('100%')
.height('100%')
.layoutWeight(1)
.objectFit(ImageFit.Contain)
}
.width(`100%`)
}
}
const PHOTO_DEFAULT_SELECT_NUMBER: number = 9; //数量
async function copyPixelMap(imagePixel: PixelMap): Promise<image.PixelMap> {
let imageInfo: image.ImageInfo = await imagePixel.getImageInfo();
console.info(`copyPixelMapSize: width:${imageInfo?.size.width} height:${imageInfo?.size.height}`);
let newRegion: image.Region = {
size: { height: imageInfo.size.height, width: imageInfo.size.width },
x: 0,
y: 0
}
let newArea: image.PositionArea = {
pixels: new ArrayBuffer(imageInfo.size.height * imageInfo.size.width * 4),
offset: 0,
stride: imageInfo.stride,
region: newRegion
}
await imagePixel.readPixels(newArea);
let opts: image.InitializationOptions = { editable: true, pixelFormat: 4, size: imageInfo.size };
let imagePixelCache = await image.createPixelMap(newArea.pixels, opts);
return imagePixelCache;
}
/**
* 通过选择模式拉起photoPicker界面,用户可以选择一个或多个图片/视频。
*/
async function selectPhoto(options?: PhotoSelectOptions): Promise<Array<string>> {
try {
if (!options) {
options = new PhotoSelectOptions();
}
if (!options.MIMEType) { //可选择的媒体文件类型,若无此参数,则默认为图片和视频类型。
options.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
}
if (!options.maxSelectNumber) { //选择媒体文件数量的最大值,默认9
options.maxSelectNumber = PHOTO_DEFAULT_SELECT_NUMBER;
}
if (options.isPhotoTakingSupported == undefined) {
options.isPhotoTakingSupported = true; //支持拍照。
}
if (options.isEditSupported == undefined) {
options.isEditSupported = true; //支持编辑照片。
}
if (options.isSearchSupported == undefined) {
options.isSearchSupported = true; //支持编辑照片。
}
let photoSelectOptions: photoAccessHelper.PhotoSelectOptions = {
MIMEType: options.MIMEType,
maxSelectNumber: options.maxSelectNumber,
isPhotoTakingSupported: options.isPhotoTakingSupported,
isEditSupported: options.isEditSupported,
isSearchSupported: options.isSearchSupported,
recommendationOptions: options.recommendationOptions,
preselectedUris: options.preselectedUris
}
let photoPicker = new photoAccessHelper.PhotoViewPicker();
let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoPicker.select(photoSelectOptions)
if (photoSelectResult && photoSelectResult.photoUris && photoSelectResult.photoUris.length > 0) {
return photoSelectResult.photoUris
} else {
return [];
}
} catch (err) {
console.error(err)
return [];
}
}
class PhotoSelectOptions {
MIMEType?: photoAccessHelper.PhotoViewMIMETypes = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; //可选择的媒体文件类型,若无此参数,则默认为图片和视频类型。
maxSelectNumber?: number = PHOTO_DEFAULT_SELECT_NUMBER; //选择媒体文件数量的最大值(默认值为50,最大值为500)。
isPhotoTakingSupported?: boolean = true; //支持拍照。
isEditSupported?: boolean = true; //支持编辑照片。
isSearchSupported?: boolean = true; //支持搜索。
recommendationOptions?: photoAccessHelper.RecommendationOptions; //支持照片推荐。
preselectedUris?: Array<string>; //预选择图片的uri数据。
}
更多关于HarmonyOS 鸿蒙Next:【PixelMap】crop后,显示到Image控件中仍然未被截取的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
针对帖子标题“HarmonyOS 鸿蒙Next:【PixelMap】crop后,显示到Image控件中仍然未被截取”的问题,这里提供直接的专业解答:
在HarmonyOS中,如果你在使用PixelMap进行裁剪(crop)操作后,发现显示到Image控件中的内容并未按照预期被截取,可能的原因包括但不限于:
-
裁剪区域设置不正确:确保你设置的裁剪区域的坐标和尺寸是正确的,且该区域完全位于原始PixelMap的范围内。
-
Image控件刷新问题:裁剪后的PixelMap需要重新设置给Image控件,并确保Image控件进行了刷新。可以通过调用Image控件的
setImage(PixelMap pixelMap)
方法来更新显示的图像,并检查是否有必要手动触发控件的刷新。 -
资源或内存管理问题:确认裁剪操作没有导致内存泄漏或资源未被正确释放,这可能会影响后续图像的正常显示。
-
Image控件属性设置:检查Image控件的属性设置,确保没有设置会覆盖或影响图像显示的属性,如缩放模式、透明度等。
如果以上检查均无误,但问题依旧存在,请考虑是否是系统或框架层面的bug。此时,如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html。