HarmonyOS 鸿蒙Next 图片主色取值问题

发布于 1周前 作者 songsunli 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 图片主色取值问题
图片地址:https://mfs.oilchem.net/common/group1/M00/2A/D3/rBKW3mbqJZ-AC3DVAAFh4rD8pSg394.jpg 主色取的值:color[ARGB]=255,198,211,193 图片明明主色调是蓝色,为什么取出来的主色调是绿色?



/**
 * 获取图片主色
 * @param url 图片url
 */
getPicMainColor(url: string) {
  http.createHttp().request(url, (error: BusinessError, data: http.HttpResponse) => {
    if (error) {
      console.error(`http request failed with. Code: ${error.code}, message: ${error.message}`);
    } else {
      let OutData: http.HttpResponse = data

      let code: http.ResponseCode | number = OutData.responseCode
      if (http.ResponseCode.OK === code) {
        let imageData: ArrayBuffer = OutData.result as ArrayBuffer;
        let imageSource: image.ImageSource = image.createImageSource(imageData);

        class tmp {
          height: number = 175
          width: number = 98
        }

        let options: Record<string, number | boolean | tmp> = {
          'alphaType': 0, // 透明度
          'editable': false, // 是否可编辑
          'pixelFormat': 3, // 像素格式
          'scaleMode': 1, // 缩略值
          'size': { height: 175, width: 98 }
        } // 创建图片大小

        imageSource.createPixelMap(options).then((pixelMap: PixelMap) => {
          effectKit.createColorPicker(pixelMap, (error, colorPicker) => {
            if (error) {
              console.error('Failed to create color picker.');
            } else {
              console.info('Succeeded in creating color picker.');
              colorPicker.getMainColor().then(color => {
                this.titleColorR = color.red
                this.titleColorG = color.green
                this.titleColorB = color.blue
                console.info('Succeeded in getting main color.');
                console.info(`color[ARGB]=${color.alpha},${color.red},${color.green},${color.blue}`);
              })
            }
          })
        })
      }
    }
  })
}

更多关于HarmonyOS 鸿蒙Next 图片主色取值问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复
图像占比最多的颜色更侧重于颜色出现的频率。而图片主色不仅考虑了颜色出现的频率,还考虑了颜色在图像中的分布情况。例如,如果图像中有大量的蓝色,那么即使蓝色的出现频率很高,它也可能不会被选为图片主色,因为它在图像中的分布可能并不均匀,色彩饱和度不足等。图片主色的判断通常需要更复杂的算法,可能涉及到颜色空间的转换、色彩饱和度的计算等,以确保选择的主色能够准确反映图像的整体色彩特征,适合需要代表性颜色的场景。
在此图中蓝色虽然占比最多却属于背景不具备代表性的色彩,因此如果您的需求是想获取占比最多的颜色应使用getLargestProportionColor(), 如果想获取主色应使用getMainColor()。

更多关于HarmonyOS 鸿蒙Next 图片主色取值问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


import { promptAction } from '@kit.ArkUI';
import {getImageColor} from './ImageUtils'
import { HashMap } from '@kit.ArkTS';

@Entry
@Component
struct SwiperPage {
  @State message: string = 'Hello World';

  @State baseColors: Array<[
    ResourceColor,
    number
  ]> = [[Color.Blue, 0.0], [0x0000ff, 0.3], [0xff0000, 1.0], ]

  @State baseColorsCol2: Array<[
    ResourceColor,
    number
  ]> = [[Color.Blue, 0.0], [0x0000ff, 0.3], [0xff0000, 1.0], ]
  swiperController:SwiperController = new SwiperController()

  @State colorMap: HashMap<string, ESObject> = new HashMap();

  @State rowHeight: number = 0;

  swiperItems: SwiperItemData[] = [
    // new SwiperItemData('https://xxxxx', '内容1'),
    // new SwiperItemData('https://xxxxx', '内容2'),
    // new SwiperItemData('https://xxxxx', '内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3'),
    new SwiperItemData('http://xxxxx', '内容1'),
    new SwiperItemData('http://xxxxx', '内容1'),
    new SwiperItemData('http://xxxxx', '内容1'),
    new SwiperItemData('https://xxxxx', '内容1'),
  ]

  newsItems: NewsItemData[] = [
    new NewsItemData('学习卡|坚持以人民为中心谋划和和推进改革', '央视新闻客户端 08-26'),
    new NewsItemData('习言道|中国共产党始终把统一战线摆在重要位置', '中国新闻网 08-26'),
    new NewsItemData('习言道|中国共产党始终把统一战线摆在重要位置习言道|中国共产党始终把统一战线摆在重要位置习言道|中国共产党始终把统一战线摆在重要位置', '中国新闻网 08-26'),
    new NewsItemData('习言道|中国共产党始终', '中国新闻网 08-26'),
    new NewsItemData('习言道|中国共产党始终把统一战线摆在重要位置', '中国新闻网 08-26'),
  ]

  aboutToAppear(): void {
  }

  build() {
    Column() {
      Stack() {
        Row(){
          Column().width('50%').height(this.rowHeight).backgroundColor(Color.Red).linearGradient({
            angle: 180,
            colors: this.baseColors
          })
          Column().width('50%').height(this.rowHeight).backgroundColor(Color.Black).linearGradient({
            angle: 180,
            colors: this.baseColorsCol2
          })
        }
        Row() {
          this.NewsBuilder(this.newsItems)
        }.zIndex(2)
        .padding({left:5, right: 5}) .onAreaChange((oldValue: Area, newValue: Area) => {
          console.log('###########', JSON.stringify(newValue))
          this.rowHeight = newValue.height as number;
        })
      }
      this.SwiperBuilder(this.swiperItems)
    }
  }

  @Builder
  NewsBuilder(items:NewsItemData[]) {
    Column(){
      ForEach(items, (item: NewsItemData) =>  {
        Column() {
          Text(item.title).fontSize(20).margin({bottom: 5}).constraintSize({minHeight: 50})
          Text(item.from).fontSize(12).fontColor('#6a000000')
        }.margin({bottom: 10})
        .alignItems(HorizontalAlign.Start)
        .onClick(() => {
          promptAction.showDialog({message: '功能开发中'})
        })
      })
    }.margin({top: 30})
    .padding({left: 5, right:5, top: 10, bottom: 10})
    .width('100%')
    .alignItems(HorizontalAlign.Start)
    .backgroundColor(Color.White)
    .borderRadius(8)
  }

  @Builder
  SwiperBuilder(items:SwiperItemData[]) {
    Row() {
      Swiper(this.swiperController) {
        ForEach(items,
          (item: SwiperItemData, index: number) => {
              Image(item.iconUrl).width('100%').onClick(() => {
                promptAction.showDialog({ message: '功能开发中' })
              }).onComplete(event => {
                if(event) {
                  getImageColor(item.iconUrl, event.width -1).then(result => {
                    console.log('############', result);
                    if(result)  {
                      let colorAry = result.split(',')
                      if(index === 0) {
                        console.log('############111', result);
                          this.baseColors.splice(2,1, [colorAry[0], 1.0])
                          this.baseColorsCol2.splice(2,1, [colorAry[1], 1.0])
                      }
                      this.colorMap.set(item.iconUrl, {leftColor: colorAry[0], rightColor: colorAry[1]})
                    }

                  })
                }
              })
                .overlay(this.textBuilder(item.content), {
                  align: Alignment.Bottom,
                  offset: { x: 10, y: -15 },
                })

          }, (item: SwiperItemData) => JSON.stringify(item))
      }
      .onChange((index: number) => {

        let colorObj:ESObject = this.colorMap.get(items[index].iconUrl);
        if(colorObj) {
          this.baseColors.splice(2,1, [colorObj.leftColor, 1.0])
          this.baseColorsCol2.splice(2,1, [colorObj.rightColor, 1.0])
        }

      })
    }
  }

  @Builder
  textBuilder(content: string) {
    Text(content).fontColor(Color.White)
      .fontSize(20)
  }
}

export class NewsItemData{
  title: string;
  from: string

  constructor(title: string, from: string) {
    this.title = title;
    this.from = from;
  }
}

export class SwiperItemData{
  iconUrl: string;
  content: string

  constructor(iconUrl: string, content: string) {
    this.iconUrl = iconUrl;
    this.content = content;
  }
}

在HarmonyOS鸿蒙Next系统中,图片主色取值通常依赖于图像处理库或系统提供的API。以下是如何在鸿蒙系统中直接通过API获取图片主色的方法概述:

  1. 加载图片:使用鸿蒙提供的图片加载接口,如BitmapFactory类(假设鸿蒙有类似Android的API设计,实际请以鸿蒙官方文档为准),将图片加载为位图对象。

  2. 分析像素:通过遍历位图的像素数据,统计各颜色分量的出现频率。可以使用Bitmap.getPixel方法获取单个像素值,然后分析RGB分量。

  3. 确定主色:根据统计结果,找出出现频率最高的颜色作为图片的主色。这可能需要一个颜色频率统计的数据结构,如哈希表。

  4. 优化:为提高效率,可以仅分析图片的抽样像素,或者采用更复杂但高效的算法,如K均值聚类,来近似确定主色。

  5. API调用:如果鸿蒙系统提供了直接获取图片主色的API,优先使用这些API,因为它们通常经过了优化,效率更高。

示例代码(伪代码,实际需根据鸿蒙API实现):

Bitmap bitmap = loadImage("path/to/image");
Color primaryColor = getPrimaryColor(bitmap);

其中getPrimaryColor函数封装了上述步骤。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部