HarmonyOS鸿蒙Next中如何基于图片主色设置毛玻璃效果

HarmonyOS鸿蒙Next中如何基于图片主色设置毛玻璃效果 给定一张背景图,基于图片的主色,如何产生毛玻璃效果?

3 回复

【解决方案】

1、获取本地图片,并解码(参考) 2、基于ColorPicker.getMainColorSync取主色(参考) 3、通过backgroundEffect属性,设置模糊效果(参考

效果

图片

代码

import { resourceManager } from '@kit.LocalizationKit';
import { image } from '@kit.ImageKit';
import { effectKit } from '@kit.ArkGraphics2D';
import { BusinessError } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct Index {
  @State largestColor: string = '';
  // 替换为本地图片
  private imageResource = $r('app.media.image4');

  async aboutToAppear() {
    try {
      const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
      const resourceMgr: resourceManager.ResourceManager = context.resourceManager;
      const fileData: Uint8Array = await resourceMgr.getMediaContent(this.imageResource.id);
      const buffer = fileData.buffer as ArrayBuffer;
      const imageSource: image.ImageSource = image.createImageSource(buffer);
      const pixelMap: image.PixelMap = await imageSource.createPixelMap();

      effectKit.createColorPicker(pixelMap, (err, colorPicker) => {
        let largestColor = colorPicker.getMainColorSync();
        let red = largestColor.red;
        let green = largestColor.green;
        let blue = largestColor.blue;
        this.largestColor = `rgba(${red},${green},${blue},0.6)`;
        console.info('{red:', largestColor.red, 'green:', largestColor.green, 'blue:',
          largestColor.blue, 'alpha:', largestColor.alpha, '}');
      })
    } catch (error) {
      let err = error as BusinessError;
      console.error(`createColorPicker fail. code = ${err.code}, message = ${err.message}`);
    }
  }

  build() {
    Row() {
      Row()
        .width('100%')
        .height('100%')
        .backgroundEffect({
          radius: 20,
          saturation: 1,
          brightness: 1,
          color: this.largestColor,
        })
    }
    .height(300)
    .backgroundImage(this.imageResource)
  }
}

更多关于HarmonyOS鸿蒙Next中如何基于图片主色设置毛玻璃效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,可通过@ohos.image模块的PixelMap获取图片主色。使用getImageColor方法提取主色值后,结合@ohos.graphics.effect模块的Filter功能,将主色作为毛玻璃效果的基色。通过BackdropBlur滤镜设置模糊半径,并叠加主色透明度调整,实现基于主色的毛玻璃效果。

在HarmonyOS Next中,基于图片主色实现毛玻璃效果,核心是提取图片主色并配合背景模糊。以下是关键步骤和代码思路:

1. 提取图片主色

使用 @ohos.multimedia.image@ohos.image 模块分析图片像素,计算平均色或频率最高的颜色:

import image from '@ohos.multimedia.image';
import { BusinessError } from '@ohos.base';

async function getDominantColor(pixelMap: image.PixelMap): Promise<number> {
  const colorCount: Map<number, number> = new Map();
  const buffer = await pixelMap.readPixelsToBuffer();
  const pixels = new Uint8Array(buffer.buffer);

  for (let i = 0; i < pixels.length; i += 4) {
    const rgba = (pixels[i] << 24) | (pixels[i + 1] << 16) | (pixels[i + 2] << 8) | pixels[i + 3];
    colorCount.set(rgba, (colorCount.get(rgba) || 0) + 1);
  }

  let maxCount = 0;
  let dominantColor = 0;
  colorCount.forEach((count, color) => {
    if (count > maxCount) {
      maxCount = count;
      dominantColor = color;
    }
  });
  return dominantColor;
}

2. 创建毛玻璃效果组件

结合主色与 BackdropBlur 滤镜:

@Component
struct FrostedGlass {
  @State dominantColor: string = '#000000';
  private pixelMap?: image.PixelMap;

  aboutToAppear() {
    // 加载图片并提取主色
    this.loadImageAndCalculateColor();
  }

  build() {
    Column() {
      // 背景层:主色半透明 + 模糊
      Stack() {
        // 主色背景
        Column()
          .width('100%')
          .height('100%')
          .backgroundColor(this.dominantColor + '66') // 追加透明度

        // 模糊层
        Column()
          .width('100%')
          .height('100%')
          .backdropBlur(10) // 模糊半径
          .backgroundBlurStyle(BlurStyle.THIN) // 模糊样式
      }
    }
  }
}

3. 动态效果优化

  • 性能:大图片建议在 Worker 线程处理颜色提取
  • 缓存:对已分析图片缓存主色结果
  • 交互:可结合 @AnimatableExtend 实现模糊度动态变化

注意事项

  • 主色提取算法可根据场景调整(如忽略透明像素)
  • 模糊半径建议 5-15 范围,过大会影响性能
  • 实时性要求高的场景可考虑缩略图分析

此方案通过分离颜色提取和模糊渲染,兼顾效果与性能,适用于卡片、浮层等需要视觉聚焦的场景。

回到顶部