首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

颤动/Dart以相同格式重写图像

基础概念

颤动(Dithering)是一种用于在有限的颜色空间中表示更丰富颜色范围的视觉效果技术。它通过在图像中添加微小的噪声来模拟更多的颜色层次,从而减少颜色量化带来的视觉伪像。

Dart是一种由Google开发的客户端优化语言,用于构建Web、服务器、移动和物联网应用程序。

相关优势

  1. 视觉效果提升:颤动可以显著提高图像在有限颜色空间中的视觉效果。
  2. 颜色深度扩展:通过颤动技术,可以在较低的颜色深度下显示更丰富的颜色。
  3. 跨平台兼容性:Dart语言支持跨平台开发,可以在不同的环境中运行。

类型

颤动主要分为两种类型:

  1. 有序颤动(Ordered Dithering):使用预定义的图案来添加噪声。
  2. 无序颤动(Random Dithering):使用随机噪声来模拟更多的颜色层次。

应用场景

颤动技术广泛应用于图像处理、数字艺术、打印和显示设备等领域。

示例代码

以下是一个使用Dart语言实现有序颤动的示例代码:

代码语言:txt
复制
import 'dart:ui' as ui;
import 'dart:io';
import 'package:flutter/material.dart';

class DitheredImage extends StatelessWidget {
  final String imagePath;

  DitheredImage({required this.imagePath});

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<ui.Image>(
      future: _loadImage(imagePath),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return CustomPaint(
            size: Size(snapshot.data!.width.toDouble(), snapshot.data!.height.toDouble()),
            painter: DitherPainter(image: snapshot.data!),
          );
        } else {
          return Center(child: CircularProgressIndicator());
        }
      },
    );
  }

  Future<ui.Image> _loadImage(String imagePath) async {
    final image = await ImageLoader.load(imagePath);
    return image;
  }
}

class DitherPainter extends CustomPainter {
  final ui.Image image;

  DitherPainter({required this.image});

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint();
    final ditherPattern = [
      0, 48, 12, 60, 3, 51, 15, 63,
      32, 16, 44, 28, 35, 19, 47, 31,
      8, 56, 4, 52, 11, 59, 7, 55,
      40, 24, 36, 20, 43, 27, 39, 23,
      2, 50, 14, 62, 1, 49, 13, 61,
      34, 18, 46, 30, 33, 17, 45, 29,
      10, 58, 6, 54, 9, 57, 5, 53,
      42, 26, 38, 22, 41, 25, 37, 21,
    ];

    final codec = await ui.instantiateImageCodec(image.toByteData(format: ui.ImageByteFormat.rawRgba)!);
    final frame = await codec.getNextFrame();
    final pixels = frame.buffer.asUint8List();

    final width = image.width;
    final height = image.height;
    final bytesPerPixel = 4;

    for (int y = 0; y < height; y += 2) {
      for (int x = 0; x < width; x += 2) {
        int index = (y * width + x) * bytesPerPixel;
        int r = pixels[index];
        int g = pixels[index + 1];
        int b = pixels[index + 2];

        int ditherIndex = ditherPattern[(y / 2) * (width / 2) + (x / 2)];
        int rDither = (r + (ditherIndex % 16) * 17) % 256;
        int gDither = (g + (ditherIndex / 16) * 17) % 256;
        int bDither = (b + (ditherIndex % 16) * 17) % 256;

        pixels[index] = rDither;
        pixels[index + 1] = gDither;
        pixels[index + 2] = bDither;
      }
    }

    final newImage = await ui.instantiateImageCodec(pixels.buffer.asUint8List());
    final newFrame = await newImage.getNextFrame();
    final newPixels = newFrame.buffer.asUint8List();

    canvas.drawImage(ui.Image.fromBytes(width, height, newPixels), Offset.zero);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

class ImageLoader {
  static Future<ui.Image> load(String imagePath) async {
    final data = await rootBundle.load(imagePath);
    final codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
    final frame = await codec.getNextFrame();
    return frame.image;
  }
}

参考链接

解决问题的思路

  1. 加载图像:使用ImageLoader类加载图像。
  2. 应用颤动算法:在DitherPainter类中实现有序颤动算法。
  3. 绘制图像:将处理后的图像绘制到画布上。

通过这种方式,可以在Dart中实现图像的颤动效果,从而提升图像的视觉效果。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【Flutter】评级对话框组件

这个库是最好的,因为它伴随着星级评价和联系,甚至可以滑动评级并发光进行星级评价。之所以命名为“等级”对话框,是因为该库将识别您在颤动的星形图标上做出的手势提供等级。...android.enableR8=true android.useAndroidX=true android.enableJetifier=true 在libs目录下创建 「demo_screen.dart...在此对话框中,我们将添加」ratingColor」表示评级栏(星形图标和发光效果)的颜色,「标题」,「消息」表示对话框的消息/描述文本,「图像」,「submitButton」表示提交按钮的标签/文本,「...在此对话框中,您将看到我们将添加图像,标题,描述,星级,评论的textField和最后一个提交按钮。另外,我们将在右上角的十字图标上添加“取消”。...完整实现 import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package

4.1K50
  • Flutter 卡片选择器

    该演示视频展示了如何在颤动中创建卡选择器。它显示了flutter应用程序中使用card_selector软件包的卡选择器的工作方式。它显示了堆叠的卡片,动画,从左到右或从右到左刷卡。...card_selector: ^0.1.0 添加 asset assets: - assets/ 导入 import 'package:card_selector/card_selector.dart...他的子属性添加了Stack(),**并在内部添加了图像。我们将添加一个列小部件,在内部添加卡的详细信息,例如银行名称,类型,编号和分支。所有数据均来自json文件。...'; import 'dart:convert'; import 'package:card_selector/card_selector.dart'; import 'package:flutter_card_selector_demo.../amount_page.dart'; import 'package:flutter_card_selector_demo/card_page.dart'; class HomePage extends

    7.4K20

    掌握这个关键技术,让你的APP开发事半功倍!——Flutter与其他方案的区别

    与用于构建移动应用程序的其他大多数框架不同,Flutter是重写了一整套包括底层渲染逻辑和上层开发语言的完整解决方案。...这需要从图像显示的基本原理说起。计算机系统中,图像的显示需要CPU、GPU和显示器一起配合完成:CPU负责图像数据计算,GPU负责图像数据渲染,而显示器则负责最终图像显示。...CPU把计算好的、需要显示的内容交给GPU,由GPU完成渲染后放入帧缓冲区,随后视频控制器根据垂直同步信号(VSync)每秒60次的速度,从帧缓冲区读取帧数据交由显示器完成图像显示。...构建Flutter的关键技术,即Skia和Dart。 3 Skia是啥? 先了解底层图像渲染引擎Skia。...界面渲染过程为例,介绍Flutter是如何工作。 页面中的各界面元素(Widget)树的形式组织,即控件树。Flutter通过控件树中的每个控件创建不同类型的渲染对象,组成渲染对象树。

    50420

    什么岗位需要学习 OpenGL ES ?说说 3.X 的新特性

    为什么学习 OpenGL ES 音视频开发,渲染引擎,游戏开发,VR(XR),图像视频特效,这些方向的岗位都要求掌握 OpenGL 开发。...sRGB 纹理,通常用于存储和显示经过 sRGB gamma 校正的图像获得更准确和更自然的颜色显示效果。 浮点纹理,常用于计算着色器(Compute Shader)。 着色器 二进制程序文件。...在 OpenGL ES 3.0 中,完全链接过的二进制程序文件可以保存为离线二进制格式,运行时不需要链接步骤。这有助于减少应用程序的加载时间。 统一变量块。...OpenGL ES 3.0 引入了 glDrawArraysInstanced 和 glDrawElementsInstanced 函数,它们允许开发者在不同的位置上绘制多个具有相同网格的物体,每个物体可以有不同的变换...减少锯齿和边缘的颤动,从而改善图像的平滑度和质量。 帧缓冲区失效机制。

    25900

    Flutter 2.5正式版发布,带来重大更新

    以前某些图像的内存在响应 Dart VM 的 GC 执行时会延迟回收,作为早期版本中的解决方法,Flutter 引擎会通过 Dart VM 的 GC 回收暗示图像内存可以回收,这在理论上可以实现了更及时的内存回收...Dart 2.14:格式、语言特性、发布和 linting 开箱即用 此版本的 Flutter和Dart 2.14是一起发布的。...新版本的Dart 带有新的格式,使级联更加清晰;新的 pub 支持忽略文件,以及新的语言功能,包括三重移位运算符的回归。...#3898 [image_picker] 图像选择器修复相机设备 #3956 [image_picker] 将相机捕获的存储位置更改为 Android 上的内部缓存,符合新的 Google Play...除此之外,开发者还可能对适用于 Dart 文件的“Fix All”命令(#3445、#3469)感兴趣,并且可以一步修复所有与dart fix相同的问题。

    4.4K50

    10分钟了解Flutter跨平台运行原理!

    三、Flutter运行原理 如前面已提到的那样,Flutter是重写了一整套包括底层渲染逻辑和上层开发语言的完整解决方案。...我们从图像显示的基本原理说起。 在计算机系统中,图像的显示需要CPU、GPU和显示器一起配合完成:CPU负责图像数据计算,GPU负责图像数据渲染,而显示器则负责最终图像显示。...CPU把计算好的、需要显示的内容交给GPU,由GPU完成渲染后放入帧缓冲区,随后视频控制器根据垂直同步信号(VSync)每秒60次的速度,从帧缓冲区读取帧数据交由显示器完成图像显示。...接下来,界面渲染过程为例,介绍Flutter是如何工作的。 页面中的各界面元素(Widget)树的形式组织,即控件树。Flutter通过控件树中的每个控件创建不同类型的渲染对象,组成渲染对象树。...Flutter的渲染树层级通常很多,直接交付给渲染引擎进行多图层渲染,可能会出现大量渲染内容的重复绘制,所以还需要先进行一次图层合成,即将所有的图层根据大小、层级、透明度等规则计算出最终的显示效果,将相同的图层归类合并

    6.6K41

    Flutter 2.5正式版发布,带来多项重大更新

    以前某些图像的内存在响应 Dart VM 的 GC 执行时会延迟回收,作为早期版本中的解决方法,Flutter 引擎会通过 Dart VM 的 GC 回收暗示图像内存可以回收,这在理论上可以实现了更及时的内存回收...Dart 2.14:格式、语言特性、发布和 linting 开箱即用 此版本的 Flutter和Dart 2.14是一起发布的。...新版本的Dart 带有新的格式,使级联更加清晰;新的 pub 支持忽略文件,以及新的语言功能,包括三重移位运算符的回归。...#3898 image_picker 图像选择器修复相机设备 #3956 image_picker 将相机捕获的存储位置更改为 Android 上的内部缓存,符合新的 Google Play 存储要求...除此之外,开发者还可能对适用于 Dart 文件的“Fix All”命令(#3445、#3469)感兴趣,并且可以一步修复所有与dart fix相同的问题。

    3.6K00

    Flutter 3.7更新详解

    我们对 gen-l10n 进行了重写支持下述特性: 描述性的语法错误 嵌套或多个复数、选择和占位的消息内容 更多内容可以了解已经更新的 Flutter 应用里的国际化 文档。...此外,Flutter 引擎 不再上报 Dart VM 中的 GPU 图像的大小。...如上所述,当这些图像资源不再被需要时已由框架手动释放,如果这时继续按照 GPU 内存大小的 GC 策略上报至 Dart,会导致不必要的堆内存压力并进一步触发无效的 GC。...类似的方法同样应用到了 Flutter 引擎中,用于回收 dart:ui 原生对象的 隐式内存占用。 在我们的测试中,此更改省去了 widget 创建 GPU 常驻图像构建帧时的同步 GC 工作。...此外,键盘动画也通过 CADisplayLink 设定了与 Flutter 引擎里 animator 相同的刷新率。

    3.2K00

    【Flutter】Dart 面向对象 ( 类定义 | 类的继承 | 私有变量 | 可选参数 | 默认参数 | 初始化列表 )

    基本特点 : 封装 : 将现实中存在的事务封装成类 ; 继承 : 使用现有类的功能 , 无需重写现有类的变量及方法 , 只实现扩展内容 ; 多态 : 子类对象可以赋值给父类类型变量 ; 类中定义的内容...Person(this.name, this.age); 重写 Object 父类方法 : // 重写父类的方法 @override String toString() { return...toString() { return "$name : $age"; } } 三、 类的继承 ---- 使用 extends 关键字定义子类 , 注意如果父类有非空参数的构造函数, 子类必须实现相同参数的构造函数...以下划线开始的变量是私有变量 int _grade; String school; String city; String address; // 如果父类有非空参数的构造函数, 子类必须实现相同参数的构造函数...以下划线开始的变量是私有变量 int _grade; String school; String city; String address; // 如果父类有非空参数的构造函数, 子类必须实现相同参数的构造函数

    1.9K00

    Dart 知识点 - 抽象类和接口

    抽象类一般会被定义为父类,给子类继承 抽象类的定义格式 格式如下: abstract class className { // 成员变量 [static][const][final] type...不熟悉的读者,可以进入文章 Dart 知识点 - 面向对象基础学习,这里不再赘述。 应用例子 我们定义一个抽象类 Shape,然后定义正方形 Square 类来继承抽象类并重写抽象类的方法。...如果实现的类是普通类,需要将普通类和抽象类中的方法和属性全部重写一遍。 Dart 中只允许继承一个类,但是可以实现多个接口。...@override void eat() { } // 重写游泳的方法 @override void swim() { } // 重写散步的方法...后面跟的是父类,implements 后面跟的是接口 class Dog extends Animal implements SwimAbility, WalkAbility { } 往期精彩推荐 Dart

    31720

    MBAS2024——多类别双心房分割挑战赛

    一、MBAS2024介绍 心房颤动 (AF) 是最常见的心律失常形式,与大量的发病率和死亡率相关。由于缺乏对直接维持人类心房中房颤的潜在心房解剖结构的基本了解,目前房颤的临床治疗效果不佳。...在2018 年左心房挑战的基础上,这一新挑战扩大到包括左心房和右心房及其壁,重点关注 LGE-MRI 的多类机器学习,增强房颤患者的消融。...这些新的人工智能和临床方法不仅在心脏分析中发挥了重大范式转变,而且有可能应用于各个医学领域,旨在完善治疗持续性心房颤动的消融策略。...二、MBAS2024任务 LGE-MRI图像上的三类解剖结构分割:左心房,右心房,房壁。...2、分析ROI图像,得到图像平均大小是580x404x44,因此将图像缩放到固定大小512x512x48。

    12410

    dart系列之:dart类的扩展

    dart系列之:dart类的扩展 文章目录 简介 使用extends 抽象类和接口 mixins 总结 简介 虽然dart中的类只能有一个父类,也就是单继承的,但是dart提供了mixin语法来绕过这样限制...上面的例子中,我们用到了@override注解,他表示子类对父类方法或者属性的重写。...在使用@override中,我们需要注意的是,子类对父类的实现会有下面几个限制: 子类的实现方法的返回值,必须和父类返回值相同,或者是父类返回值的子类。...子类的实现方法的参数,必须和父类方法参数相同,或者是父类参数的父类。 子类方法的参数必须和父类的参数个数相同。...String name=''; void myName() { print('my name is:'+name); } } 在mixin中可以定义有用的方法和属性,继承mixin的类可以重写对应的属性和方法

    72710

    《Flutter》-- 4.Flutter组件基础

    创建无状态的组件,需要继承StatelessWidget,并重写build()。 4.1.2 StatefulWidget StatefulWidget表示有状态的组件。...创建有状态的组件,需要继承StatefulWidget,然后在该组件中创建状态对象,并重写build()。...所有Materail组件库的按钮都有两个相同点:一是按下时会有水波动画,另一个是都有一个onPressed属性来设置单击回调。...BoxFit.fitHeight:从高度上充满空间,宽度会按比例缩放,图片不会变形,超出显示空间部分会被剪裁; BoxFit.scaleDown:与BoxFit.contain的效果差不多,但此属性会缩小图像确保图像位于显示空间内...inputFormatters:指定输入格式,当用户输入的内容发生改变时,会根据指定的格式来进行校验。 enabled:是否禁用输入框。

    12.5K30

    Pigeon- Flutter多端接口一致性以及规范化管理实践

    下文0.1.7版本为例。 为何需要Pigeon 在hybird开发中,前端需要native能力,需要native双端开发提供接口。...Pigeon的作用 Flutter官方提供的Pigeon插件,通过dart入口,生成双端通用的模板代码,Native部分只需通过重写模板内的接口,无需关心methodChannel部分的具体实现,入参,...(这里的确不同版本使用起来差异较大,笔者这里接入的时候0.1.7与0.1.10,pigeon默认导出和使用都不相同) 创建package ps:如果接入已有plugin库,可以跳过此部分,直接看接入部分...这里pigeons/pigeonDemoMessage.dart为例 import 'package:pigeon/pigeon.dart'; class DemoReply {   String ...StringSink sink) =>     generateJava(options.javaOptions, parseResults.root, sink)); } 这里每个具体生成输出的函数就比较简单,这里dart

    3.7K52

    腾讯云IM Flutter-原生混合开发方案接入实践

    有的时候,使用Flutter重写您现有的应用程序是不现实的。如果您想在现有APP中,使用腾讯云IM的能力,推荐采用混合开发方案,即将Flutter模块,嵌入您的原生开发APP项目中。...每次你在你的颤动模块中修改代码时,你都必须运行 flutter build ios-framework.因此,建议在线上环境,使用本方案。具体步骤:在您的Flutter module中,运行如下代码。...在该目录中,您可以运行与在任何其他 Flutter 项目中相同的 Flutter 命令,例如 flutter run --debug 或 flutter build ios。...由于不同厂商的离线推送接入步骤不一致,本文OPPO为例,全部厂商接入方案,可查看本文档.在腾讯云IM控制台中,新增OPPO的推送证书,点击后续动作 选择 打开应用内指定页面,应用内页面 Activity...Native初始化并登录 iOS Swift 代码为例,演示如何在 Native 层,初始化并登录。

    7.1K50
    领券