• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *  http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15import router from '@ohos.router';
16import image from '@ohos.multimedia.image';
17import { logger } from '../util/Logger';
18import { copyPixelMap } from '../util/CopyObj';
19import { pictureJsDatas, pictureNdkDatas } from '../model/AdjustModels';
20import { CropTasks, TaskData, Tasks } from '../model/AdjustData';
21import PixelMapQueue from '../feature/PixelMapQueue';
22import { FontColorData, MaterialData } from '../model/MaterialData';
23import { BusinessError } from '@ohos.base';
24import { DecodingPicture, EncodingPicture } from '../util/PictureUtil';
25import { NDKPictureDecoding, NDKPictureEncoding } from '../util/PictureUtil';
26
27const TAG: string = '[Sample_Picture]';
28
29@Component
30export struct PictureOptions {
31  @State pixelMap: PixelMap | undefined | null = undefined;
32  @State isPixelMapChange: boolean = false;
33  @State adjustMarkJudg: boolean = false;
34  @State currentTask: number = Tasks.ADJUST;
35  @State currentCropTask: number = CropTasks.NONE;
36  @State tempPixelMap: image.PixelMap | undefined | null = undefined;
37  @State cancelOkText: Resource | null = null;
38  @State brightnessValue: number = 0;
39  @State outSetValueOne: number = 0;
40  @State originBM: PixelMap | null = null;
41  @State cropIndex: number = 0;
42  @State canClick: boolean = true;
43  @State loading: boolean = false;
44  @State isCancelQuit: boolean = false;
45  // 选择资源素材index
46  @State resourceIndex: number = 0;
47  @State isTextMaterial: boolean = true;
48  selectedResource: Resource | undefined = $r('app.color.material_font_color_one');
49  scroller: Scroller = new Scroller();
50  brightnessOriginBM: PixelMap | null | undefined = null;
51  @State resolution: string = '';
52  @State inputValue: string = '';
53  // 分辨率的坐标
54  @State dpiX: number = 0;
55  @State dpiY: number = 0;
56  // 分辨率
57  @State dpi: string = '';
58  // 图片父容器大小
59  containerArea: Area | null = null;
60  isBrightChanging: boolean = false;
61  // fileName
62  @State jpegFileName: string = 'HdrVivid.jpg';
63  @State heifFileName: string = 'HEIFISOMultiChannelBaseColor0512V12.heic';
64  @State packingFileName: string = '';
65  private pixelMapQueue: PixelMapQueue = new PixelMapQueue();
66  pushState1: number = 0; // source
67  pushState2: number = 1; // obj
68  outState1: number = 0; // buffer
69  outState2: number = 1; // file
70  pictureStatus1: number = 0; // jpeg
71  pictureStatus2: number = 1; // heic
72  auxiliaryType: image.AuxiliaryPictureType = image.AuxiliaryPictureType.GAINMAP;
73  @State showPicture: string = '';
74
75  /**
76   * 刷新图层显示
77   */
78  flushPage(): void {
79    this.tempPixelMap = this.pixelMap;
80    this.pixelMap = null;
81    this.pixelMap = this.tempPixelMap;
82  }
83
84  async onEditCancel(): Promise<void> {
85    if (this.currentTask === Tasks.DECODEJS || this.currentTask === Tasks.ENCODEJS) {
86      this.currentTask = Tasks.ADJUST;
87      this.cropIndex = 0;
88    }
89    if (this.currentTask === Tasks.DECODENDK || this.currentTask === Tasks.ENCODENDK) {
90      this.currentTask = Tasks.MARK;
91      this.cropIndex = 0;
92    }
93
94    this.isCancelQuit = true;
95    this.outSetValueOne = 0;
96    if (this.originBM !== null && this.originBM !== undefined) {
97      this.pixelMap = await copyPixelMap(this.originBM); // 拷贝
98    }
99    // 移出一个缓存
100    const pm: image.PixelMap | undefined = this.pixelMapQueue.pop();
101    this.releasePm(pm);
102  }
103
104  /**
105   * 选择子菜单
106   * @param item
107   * @param hasInputText
108   */
109  async onSelectItem(item: TaskData): Promise<void> {
110    if (item.task !== undefined) {
111      this.currentTask = item.task;
112    }
113    if (item.text !== undefined) {
114      this.cancelOkText = item.text
115    }
116    this.originBM = await copyPixelMap(this.pixelMap!) // 拷贝
117    // 保存到队列
118    this.pixelMapQueue.push(this.originBM);
119  }
120
121  /**
122   * 多图图片解码
123   * @param pictureStatus 图片类型(0:jpeg, 1:heif)
124   * @param auxType 解码类型(1:Gain map)
125   * @returns
126   */
127  async decodingPictureJs(pictureStatus: number, auxType: image.AuxiliaryPictureType): Promise<void> {
128    logger.info(TAG, `decodingPicture start`);
129    logger.debug(TAG, `decodingPicture Type = ${auxType}`);
130    if (!pictureStatus) { // jpeg
131      this.pixelMap = await DecodingPicture(this.jpegFileName, auxType);
132    } else {
133      this.pixelMap = await DecodingPicture(this.heifFileName, auxType);
134    }
135    if (!this.pixelMap) {
136      logger.info(TAG, `decodingPicture no pixelMap`);
137      return;
138    }
139    let imageInfo: image.ImageInfo = await this.pixelMap.getImageInfo();
140    if (!imageInfo) {
141      logger.info(TAG, `decodingPicture no imageInfo`);
142      return;
143    }
144    logger.debug(TAG, `imageInfo = ${JSON.stringify(imageInfo)}`);
145    logger.debug(TAG, `imageInfo.isHdr  = ${imageInfo.isHdr}`);
146    this.flushPage();
147    logger.info(TAG, 'decodingPicture end');
148  }
149
150  /**
151   * 多图图片编码
152   * @param pushStatus 编码入参(0:source, 1:obj)
153   * @param jpegFileName 图片类型(jpeg)
154   * @param outStatus 编码出参(0:buffer, 1:file)
155   * @returns
156   */
157  async encodingPictureJs(pushStatus: number, outStatus: number): Promise<void> {
158    logger.info(TAG, 'encodingPicture start');
159    this.pixelMap = await EncodingPicture(pushStatus, this.jpegFileName, outStatus);
160    if (!this.pixelMap) {
161      logger.info(TAG, `encodingPicture no pixelMap`);
162      return;
163    }
164    let imageInfo: image.ImageInfo = await this.pixelMap.getImageInfo();
165    if (!imageInfo) {
166      logger.info(TAG, `encodingPicture no imageInfo`);
167      return;
168    }
169    logger.debug(TAG, `imageInfo = ${JSON.stringify(imageInfo)}`);
170    logger.debug(TAG, `imageInfo.isHdr  = ${imageInfo.isHdr}`);
171    this.flushPage();
172    logger.info(TAG, 'encodingPicture end');
173  }
174
175  /**
176   * Native多图图片解码
177   * @param decodingType 解码类型(1:Gain map)
178   * @returns
179   */
180  async decodingPictureNdk(auxType: image.AuxiliaryPictureType, uri: string): Promise<void> {
181    logger.info(TAG, `decodingPicture start`);
182    logger.debug(TAG, `decodingPicture Type = ${auxType}`);
183    this.pixelMap = await NDKPictureDecoding(uri, auxType);
184    if (!this.pixelMap) {
185      logger.info(TAG, `decodingPicture no pixelMap`);
186      return;
187    }
188    let imageInfo: image.ImageInfo = await this.pixelMap.getImageInfo();
189    if (!imageInfo) {
190      logger.info(TAG, `decodingImage no imageInfo`);
191      return;
192    }
193    logger.debug(TAG, `imageInfo = ${JSON.stringify(imageInfo)}`);
194    logger.debug(TAG, `imageInfo.isHdr  = ${imageInfo.isHdr}`);
195    this.flushPage();
196    logger.info(TAG, 'decodingImage end');
197  }
198
199  /**
200   * Native多图图片编码
201   * @param encodingType 编码类型(0:AUTO,1:SDR)
202   * @returns
203   */
204  async encodingPictureNdk(fileName: string, encodingObject: string, encodingResult: string): Promise<void> {
205    logger.info(TAG, 'encodingPicture start');
206    this.pixelMap = await NDKPictureEncoding(fileName, encodingObject, encodingResult);
207    if (!this.pixelMap) {
208      logger.info(TAG, `decodingPicture no pixelMap`);
209      return;
210    }
211    let imageInfo: image.ImageInfo = await this.pixelMap.getImageInfo();
212    if (!imageInfo) {
213      logger.info(TAG, `encodingPicture no imageInfo`);
214      return;
215    }
216    logger.debug(TAG, `imageInfo = ${JSON.stringify(imageInfo)}`);
217    logger.debug(TAG, `imageInfo.isHdr  = ${imageInfo.isHdr}`);
218    this.flushPage();
219    logger.info(TAG, 'encodingPicture end');
220  }
221
222  /**
223   * 底部一级菜单
224   */
225  @Builder
226  getFirstLvMenu() {
227    Row() {
228      Column() {
229        Image($r('app.media.ic_adjust'))
230          .width($r('app.float.size_30'))
231          .height($r('app.float.size_30'))
232        Text($r('app.string.edit_picture_js'))
233          .fontColor(Color.White)
234          .fontSize($r('app.float.size_16'))
235      }
236      .id('external')
237      .justifyContent(FlexAlign.Center)
238      .justifyContent(FlexAlign.Center)
239      .height('100%')
240      .width('40%')
241      .margin({ left: '10%' })
242      .backgroundColor(this.adjustMarkJudg ? Color.Black : $r('app.color.edit_image_adjust_selected'))
243      .onClick(async () => {
244        this.adjustMarkJudg = false;
245        this.currentTask = Tasks.ADJUST;
246      })
247
248      Column() {
249        Image($r('app.media.ic_mark'))
250          .width($r('app.float.size_30'))
251          .height($r('app.float.size_30'))
252        Text($r('app.string.edit_picture_native'))
253          .fontColor(Color.White)
254          .fontSize($r('app.float.size_16'))
255      }
256      .id('inner')
257      .justifyContent(FlexAlign.Center)
258      .onClick(() => {
259        this.adjustMarkJudg = true;
260        this.currentTask = Tasks.MARK;
261      })
262      .backgroundColor(this.adjustMarkJudg ? $r('app.color.edit_image_adjust_selected') : Color.Black)
263      .height('100%')
264      .width('40%')
265      .margin({ right: '10%' })
266    }
267    .height('9%')
268    .width('100%')
269  }
270
271  releasePm(pm: PixelMap | undefined): void {
272    if (!pm) {
273      return
274    }
275
276    pm.release().catch((err: BusinessError) => {
277      logger.error('pm release failed:' + JSON.stringify(err));
278    });
279  }
280
281  @Builder
282  CancelOrOk(text: string | Resource) {
283    Row() {
284      Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
285        Image($r('app.media.ic_cancel'))
286          .width($r('app.float.size_30'))
287          .height($r('app.float.size_30'))
288          .onClick(async () => {
289            await this.onEditCancel();
290          })
291          .margin({ left: '10%' })
292          .id('cancel')
293
294        Text(text)
295          .fontColor(Color.White)
296          .fontSize($r('app.float.size_18'))// 根据【修改hdr设置】文字长度,设置宽度为120
297          .width(this.currentTask === Tasks.HDR ? $r('app.float.size_120') : $r('app.float.size_40'))
298          .height($r('app.float.size_30'))
299
300        Image($r('app.media.ic_ok'))
301          .width($r('app.float.size_30'))
302          .height($r('app.float.size_30'))
303          .margin({ right: '10%' })
304          .onClick(() => {
305            if (this.currentTask === Tasks.ENCODEJS || this.currentTask === Tasks.DECODEJS) {
306              this.currentTask = Tasks.ADJUST;
307              this.cropIndex = 0;
308            }
309            if (this.currentTask === Tasks.ENCODENDK || this.currentTask === Tasks.DECODENDK) {
310              this.currentTask = Tasks.MARK;
311              this.cropIndex = 0;
312            }
313            this.outSetValueOne = 0;
314          })
315          .id('ok')
316      }
317    }
318    .backgroundColor($r('app.color.edit_image_public_background'))
319    .height('9%')
320    .width('100%')
321  }
322
323  @Builder
324  getMarkTool() {
325    Row() {
326      List() {
327        ForEach(pictureNdkDatas, (item: TaskData, index) => {
328          ListItem() {
329            Column() {
330              Image(item.image)
331                .width($r('app.float.size_30'))
332                .height($r('app.float.size_30'))
333              Text(item.text)
334                .fontColor(Color.White)
335                .fontSize($r('app.float.size_15'))
336                .margin({ top: $r('app.float.size_5') })
337            }
338            .id(item.name)
339            .justifyContent(FlexAlign.Center)
340            .height('100%')
341            .width('40%')
342            .margin(index === 0 ? { left: '10%' } : { right: '10%' })
343            .onClick(async () => {
344              await this.onSelectItem(item);
345            })
346
347          }
348        })
349      }
350      .listDirection(Axis.Horizontal) // 排列方向
351      .width('100%')
352      .height('14%')
353    }
354    .backgroundColor($r('app.color.edit_image_public_background'))
355    .width('100%')
356    .justifyContent(FlexAlign.SpaceAround)
357    .alignItems(VerticalAlign.Center)
358  }
359
360  @Builder
361  getAdjustTool() {
362    Row() {
363      List() {
364        ForEach(pictureJsDatas, (item: TaskData, index) => {
365          ListItem() {
366            Column() {
367              Image(item.image)
368                .width($r('app.float.size_30'))
369                .height($r('app.float.size_30'))
370              Text(item.text)
371                .fontColor(Color.White)
372                .fontSize($r('app.float.size_15'))
373                .margin({ top: $r('app.float.size_5') })
374            }
375            .id(item.name)
376            .justifyContent(FlexAlign.Center)
377            .height('100%')
378            .width('40%')
379            .onClick(async () => {
380              if (item.task !== undefined) {
381                this.currentTask = item.task;
382              }
383              if (item.text !== undefined) {
384                this.cancelOkText = item.text
385              }
386              this.originBM = await copyPixelMap(this.pixelMap!) // 拷贝
387              // 保存到队列
388              this.pixelMapQueue.push(this.originBM);
389            })
390          }
391        })
392      }
393      .listDirection(Axis.Horizontal) // 排列方向
394      .height('14%')
395    }
396    .backgroundColor($r('app.color.edit_image_public_background'))
397    .width('100%')
398    .justifyContent(FlexAlign.SpaceAround)
399    .alignItems(VerticalAlign.Center)
400  }
401
402  @Builder
403  TextOrStickerScroll(materials: MaterialData[]) {
404    Row() {
405      Scroll() {
406        List({ scroller: this.scroller }) {
407          ForEach(materials, (item: MaterialData, index: number) => {
408            ListItem() {
409              Column() {
410                if (item instanceof FontColorData) {
411                  Text(item.getResource())
412                    .visibility(Visibility.Hidden)
413                    .width($r('app.float.size_40'))
414                    .height($r('app.float.size_40'))
415                } else {
416                  Image(item.getResource())
417                    .width($r('app.float.size_40'))
418                    .height($r('app.float.size_40'))
419                }
420              }
421              .justifyContent(FlexAlign.Center)
422              .borderRadius($r('app.float.size_10'))
423              .border(this.resourceIndex === index ?
424                {
425                  width: $r('app.float.size_3'),
426                  color: $r('app.color.edit_image_mark_scroll_selected'),
427                  radius: $r('app.float.size_10')
428                } : { width: $r('app.float.size_0'), color: $r('app.color.edit_image_mark_scroll') })
429              .backgroundColor(this.currentTask === Tasks.STICKER ? $r('app.color.edit_image_mark_scroll') : item.getResource())
430              .width($r('app.float.size_45'))
431              .height($r('app.float.size_45'))
432              .onClick(() => {
433                this.resourceIndex = index;
434                this.selectedResource = item.getResource();
435              })
436            }
437            .height('100%')
438            .width('17%')
439          })
440        }
441        .listDirection(Axis.Horizontal) // 排列方向
442        .height('14%')
443      }
444      .padding({ left: $r('app.float.size_30'), right: $r('app.float.size_30') })
445      .scrollBar(BarState.Off)
446      .scrollable(ScrollDirection.Horizontal)
447    }
448    .alignItems(VerticalAlign.Center)
449    .backgroundColor($r('app.color.edit_image_public_background'))
450    .width('100%')
451  }
452
453  @Builder
454  getTopBar() {
455    Row() {
456      Image($r('app.media.ic_public_back'))
457        .id('back')
458        .fillColor(Color.White)
459        .width($r('app.float.size_32'))
460        .height($r('app.float.size_32'))
461        .onClick(() => {
462          router.back()
463        })
464    }
465
466    .width('100%')
467    .padding({ left: $r('app.float.size_14') })
468    .margin({ top: $r('app.float.size_20') });
469  }
470
471  getResolutionText(): string {
472    const tip: string = getContext(this).resourceManager.getStringSync($r('app.string.edit_image_resolution'));
473    return tip + this.dpi;
474  }
475
476  @Builder
477  pictureDecodingToolJs() {
478    Row() {
479      Column() {
480        Image($r('app.media.ic_rotate'))
481          .width($r('app.float.size_30'))
482          .height($r('app.float.size_30'))
483        Text($r('app.string.picture_decode_jpeg'))
484          .margin({ top: $r('app.float.size_5') })
485          .fontSize($r('app.float.size_14'))
486          .fontColor(Color.White)
487      }
488      .id('jpegJs')
489      .onClick(async () => {
490        this.pixelMap = null;
491        this.showPicture = this.jpegFileName;
492        await this.decodingPictureJs(this.pictureStatus1, this.auxiliaryType); // jpeg
493      })
494
495      Column() {
496        Image($r('app.media.ic_rotate'))
497          .width($r('app.float.size_30'))
498          .height($r('app.float.size_30'))
499        Text($r('app.string.picture_decode_heif'))
500          .margin({ top: $r('app.float.size_5') })
501          .fontColor(Color.White)
502          .fontSize($r('app.float.size_14'))
503      }
504      .id('heifJs')
505      .onClick(async () => {
506        this.pixelMap = null;
507        this.showPicture = this.heifFileName;
508        await this.decodingPictureJs(this.pictureStatus2, this.auxiliaryType); // heif
509      })
510    }
511    .justifyContent(FlexAlign.SpaceAround)
512    .backgroundColor($r('app.color.edit_image_public_background'))
513    .height('14%')
514    .width('100%')
515  }
516
517  @Builder
518  pictureEncodingToolJs() {
519    Row() {
520      Column() {
521        Image($r('app.media.ic_rotate'))
522          .width($r('app.float.size_30'))
523          .height($r('app.float.size_30'))
524        Text($r('app.string.source_encode_buffer'))// 0, 0
525          .margin({ top: $r('app.float.size_5') })
526          .fontSize($r('app.float.size_14'))
527          .fontColor(Color.White)
528      }
529      .id('sourceToDataJs')
530      .onClick(async () => {
531        this.pixelMap = null;
532        this.showPicture = this.jpegFileName;
533        await this.encodingPictureJs(this.pushState1, this.outState1);
534      })
535
536      Column() {
537        Image($r('app.media.ic_rotate'))
538          .width($r('app.float.size_30'))
539          .height($r('app.float.size_30'))
540        Text($r('app.string.source_encode_file'))// 0, 1
541          .margin({ top: $r('app.float.size_5') })
542          .fontSize($r('app.float.size_14'))
543          .fontColor(Color.White)
544      }
545      .id('sourceToFileJs')
546      .onClick(async () => {
547        this.pixelMap = null;
548        this.showPicture = this.jpegFileName;
549        await this.encodingPictureJs(this.pushState1, this.outState2);
550      })
551
552      Column() {
553        Image($r('app.media.ic_rotate'))
554          .width($r('app.float.size_30'))
555          .height($r('app.float.size_30'))
556        Text($r('app.string.picture_encode_buffer'))// 1, 0
557          .margin({ top: $r('app.float.size_5') })
558          .fontColor(Color.White)
559          .fontSize($r('app.float.size_14'))
560      }
561      .id('pictureToDataJs')
562      .onClick(async () => {
563        this.pixelMap = null;
564        this.showPicture = this.jpegFileName;
565        await this.encodingPictureJs(this.pushState2, this.outState1);
566      })
567
568      Column() {
569        Image($r('app.media.ic_rotate'))
570          .width($r('app.float.size_30'))
571          .height($r('app.float.size_30'))
572        Text($r('app.string.picture_encode_file'))// 1, 1
573          .margin({ top: $r('app.float.size_5') })
574          .fontColor(Color.White)
575          .fontSize($r('app.float.size_14'))
576      }
577      .id('pictureToFileJs')
578      .onClick(async () => {
579        this.pixelMap = null;
580        this.showPicture = this.jpegFileName;
581        await this.encodingPictureJs(this.pushState2, this.outState2);
582      })
583    }
584    .justifyContent(FlexAlign.SpaceAround)
585    .backgroundColor($r('app.color.edit_image_public_background'))
586    .height('14%')
587    .width('100%')
588  }
589
590  @Builder
591  pictureDecodingToolNdk() {
592    Row() {
593      Column() {
594        Image($r('app.media.ic_rotate'))
595          .width($r('app.float.size_30'))
596          .height($r('app.float.size_30'))
597        Text($r('app.string.picture_decode_jpeg'))
598          .margin({ top: $r('app.float.size_5') })
599          .fontSize($r('app.float.size_14'))
600          .fontColor(Color.White)
601      }
602      .id('jpegNdk')
603      .onClick(async () => {
604        this.pixelMap = null;
605        this.showPicture = this.jpegFileName;
606        await this.decodingPictureNdk(this.auxiliaryType, this.jpegFileName);
607      })
608
609      Column() {
610        Image($r('app.media.ic_rotate'))
611          .width($r('app.float.size_30'))
612          .height($r('app.float.size_30'))
613        Text($r('app.string.picture_decode_heif'))
614          .margin({ top: $r('app.float.size_5') })
615          .fontColor(Color.White)
616          .fontSize($r('app.float.size_14'))
617      }
618      .id('heifNdk')
619      .onClick(async () => {
620        this.pixelMap = null;
621        this.showPicture = this.heifFileName;
622        await this.decodingPictureNdk(this.auxiliaryType, this.heifFileName);
623      })
624    }
625    .justifyContent(FlexAlign.SpaceAround)
626    .backgroundColor($r('app.color.edit_image_public_background'))
627    .height('14%')
628    .width('100%')
629  }
630
631  @Builder
632  pictureEncodingToolNdk() {
633    Row() {
634      Column() {
635        Image($r('app.media.ic_rotate'))
636          .width($r('app.float.size_30'))
637          .height($r('app.float.size_30'))
638        Text($r('app.string.source_encode_file'))
639          .margin({ top: $r('app.float.size_5') })
640          .fontSize($r('app.float.size_14'))
641          .fontColor(Color.White)
642      }
643      .id('sourceToFileNdk')
644      .onClick(async () => {
645        this.pixelMap = null;
646        this.showPicture = this.jpegFileName;
647        await this.encodingPictureNdk(this.jpegFileName, 'imageSource', 'file');
648      })
649
650      Column() {
651        Image($r('app.media.ic_rotate'))
652          .width($r('app.float.size_30'))
653          .height($r('app.float.size_30'))
654        Text($r('app.string.source_encode_buffer'))
655          .margin({ top: $r('app.float.size_5') })
656          .fontColor(Color.White)
657          .fontSize($r('app.float.size_14'))
658      }
659      .id('sourceToDataNdk')
660      .onClick(async () => {
661        this.pixelMap = null;
662        this.showPicture = this.jpegFileName;
663        await this.encodingPictureNdk(this.jpegFileName, 'imageSource', 'data');
664      })
665
666      Column() {
667        Image($r('app.media.ic_rotate'))
668          .width($r('app.float.size_30'))
669          .height($r('app.float.size_30'))
670        Text($r('app.string.picture_encode_file'))
671          .margin({ top: $r('app.float.size_5') })
672          .fontSize($r('app.float.size_14'))
673          .fontColor(Color.White)
674      }
675      .id('pictureToFileNdk')
676      .onClick(async () => {
677        this.pixelMap = null;
678        this.showPicture = this.jpegFileName;
679        await this.encodingPictureNdk(this.jpegFileName, 'picture', 'file');
680      })
681
682      Column() {
683        Image($r('app.media.ic_rotate'))
684          .width($r('app.float.size_30'))
685          .height($r('app.float.size_30'))
686        Text($r('app.string.picture_encode_buffer'))
687          .margin({ top: $r('app.float.size_5') })
688          .fontColor(Color.White)
689          .fontSize($r('app.float.size_14'))
690      }
691      .id('pictureToDataNdk')
692      .onClick(async () => {
693        this.pixelMap = null;
694        this.showPicture = this.jpegFileName;
695        await this.encodingPictureNdk(this.jpegFileName, 'picture', 'data');
696      })
697    }
698    .justifyContent(FlexAlign.SpaceAround)
699    .backgroundColor($r('app.color.edit_image_public_background'))
700    .height('14%')
701    .width('100%')
702  }
703
704  build() {
705    Column() {
706      // 顶部功能区
707      this.getTopBar()
708      // 中间操作区
709      Stack({ alignContent: Alignment.Center }) {
710        Column() {
711          Row() {
712            Text('Source graph:')
713              .fontSize(20)
714              .margin({ left: 5, right: 80 })
715              .fontColor(Color.White)
716            Text('Result graph:')
717              .fontSize(20)
718              .fontColor(Color.White)
719          }
720          .height(50)
721          .width('100%')
722
723          Flex({ justifyContent: FlexAlign.SpaceBetween, direction: FlexDirection.Row }) {
724            Image($rawfile(this.showPicture))
725              .width('100%')
726              .height(300)
727              .objectFit(ImageFit.Contain)
728              .margin(5)
729            Image(this.pixelMap)
730              .width('100%')
731              .height(300)
732              .objectFit(ImageFit.Contain)
733              .margin(5)
734          }
735        }
736      }.layoutWeight(1)
737      .onAreaChange((newValue: Area) => {
738        this.containerArea = newValue;
739      })
740
741      // 底部菜单栏
742      Column() {
743        if (this.currentTask === Tasks.MARK) {
744          this.getMarkTool();
745        } else if (this.currentTask === Tasks.ADJUST) {
746          this.getAdjustTool();
747        } else if (this.currentTask === Tasks.ENCODEJS) {
748          this.pictureEncodingToolJs();
749        } else if (this.currentTask === Tasks.DECODEJS) {
750          this.pictureDecodingToolJs();
751        } else if (this.currentTask === Tasks.ENCODENDK) {
752          this.pictureEncodingToolNdk();
753        } else if (this.currentTask === Tasks.DECODENDK) {
754          this.pictureDecodingToolNdk();
755        }
756        if (this.currentTask === Tasks.MARK || this.currentTask === Tasks.ADJUST) {
757          this.getFirstLvMenu();
758        } else {
759          this.CancelOrOk(this.cancelOkText!);
760        }
761      }
762      .width('100%')
763    }
764    .backgroundColor(Color.Black)
765    .width('100%')
766    .height('100%')
767  }
768}