img_demo.dart 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. import 'dart:ui' as ui;
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/services.dart';
  4. import 'package:vid/us/vid_us_image_data.dart';
  5. class ImageDemoPage extends StatefulWidget {
  6. const ImageDemoPage({Key? key}) : super(key: key);
  7. @override
  8. State<StatefulWidget> createState() => _ImageDemoPageState();
  9. }
  10. class _ImageDemoPageState extends State<ImageDemoPage> {
  11. /// -255~255,default:0
  12. int brightness = 0;
  13. /// -99~99,default:0
  14. int contrast = 0;
  15. ui.Image? image;
  16. @override
  17. void initState() {
  18. super.initState();
  19. _loadImg().then((value) {
  20. if (mounted) {
  21. setState(() {
  22. image = value;
  23. });
  24. }
  25. });
  26. }
  27. @override
  28. Widget build(BuildContext context) {
  29. return Material(
  30. color: Colors.green,
  31. child: FutureBuilder(
  32. future: _loadImg(),
  33. builder: (_, snapshot) {
  34. if (snapshot.connectionState == ConnectionState.done &&
  35. snapshot.hasData) {
  36. final image = snapshot.data! as ui.Image;
  37. return Column(
  38. children: [
  39. RepaintBoundary(
  40. child: CustomPaint(
  41. size: ui.Size(
  42. image.width.toDouble(),
  43. image.height.toDouble(),
  44. ),
  45. painter: _MyPainter(
  46. image,
  47. brightness: brightness,
  48. contrast: contrast,
  49. ),
  50. ),
  51. ),
  52. const SizedBox(height: 8),
  53. buildBrightnessController(),
  54. const SizedBox(height: 8),
  55. buildContrastController(),
  56. ],
  57. );
  58. }
  59. return const Center(
  60. child: CircularProgressIndicator(),
  61. );
  62. },
  63. ),
  64. );
  65. }
  66. Widget buildBrightnessController() {
  67. return Container(
  68. color: Colors.white,
  69. height: 50,
  70. width: 280,
  71. child: Row(
  72. mainAxisAlignment: MainAxisAlignment.start,
  73. children: [
  74. IconButton(
  75. onPressed: () {
  76. if (brightness < -250) return;
  77. setState(() {
  78. brightness -= 10;
  79. });
  80. },
  81. icon: const Icon(Icons.remove),
  82. ),
  83. IconButton(
  84. onPressed: () {
  85. if (brightness > 250) return;
  86. setState(() {
  87. brightness += 10;
  88. });
  89. },
  90. icon: const Icon(Icons.add),
  91. ),
  92. const SizedBox(width: 10),
  93. Text("Brightness: $brightness [-255~255]"),
  94. ],
  95. ),
  96. );
  97. }
  98. Widget buildContrastController() {
  99. return Container(
  100. color: Colors.white,
  101. height: 50,
  102. width: 280,
  103. child: Row(
  104. mainAxisAlignment: MainAxisAlignment.start,
  105. children: [
  106. IconButton(
  107. onPressed: () {
  108. if (contrast < -90) return;
  109. setState(() {
  110. contrast -= 10;
  111. });
  112. },
  113. icon: const Icon(Icons.remove),
  114. ),
  115. IconButton(
  116. onPressed: () {
  117. if (contrast > 90) return;
  118. setState(() {
  119. contrast += 10;
  120. });
  121. },
  122. icon: const Icon(Icons.add),
  123. ),
  124. const SizedBox(width: 10),
  125. Text("Contrast: $contrast (-100~100)"),
  126. ],
  127. ),
  128. );
  129. }
  130. Future<ui.Image> _loadImg() async {
  131. return await _loadJpgImg();
  132. final byteData = await rootBundle.load('assets/default.VID');
  133. final bytes = byteData.buffer.asUint8List();
  134. final vidData = VidUsImageData(bytes);
  135. final frame = vidData.getImage(0);
  136. final img = await decodeImageFromList(frame.imageData);
  137. return img;
  138. }
  139. Future<ui.Image> _loadJpgImg() async {
  140. final byteData = await rootBundle.load('assets/test.jpg');
  141. final bytes = byteData.buffer.asUint8List();
  142. final img = await decodeImageFromList(bytes);
  143. return img;
  144. }
  145. double _calcConstract(int val, double contrast) {
  146. double pval = val / 255.0;
  147. pval -= 0.5;
  148. pval *= contrast;
  149. pval += 0.5;
  150. pval *= 255;
  151. if (pval < 0) pval = 0;
  152. if (pval > 255) pval = 255;
  153. return pval;
  154. }
  155. }
  156. class _MyPainter extends CustomPainter {
  157. _MyPainter(
  158. this.image, {
  159. this.brightness = 0,
  160. this.contrast = 0,
  161. });
  162. final ui.Image image;
  163. final int brightness;
  164. final int contrast;
  165. // ignore: prefer_final_fields
  166. ui.Paint _paint = ui.Paint()..isAntiAlias = true;
  167. @override
  168. void paint(ui.Canvas canvas, ui.Size size) {
  169. // https://blog.csdn.net/hnulwt/article/details/44755025
  170. // _paint.colorFilter = const ui.ColorFilter.matrix(<double>[
  171. // 1, 0, 0, 0, 220, //
  172. // 0, 1, 0, 0, 220, //
  173. // 0, 0, 1, 0, 220, //
  174. // 0, 0, 0, 1, 0, //
  175. // ]);
  176. // double lum = brightness.toDouble();
  177. double scale = 1.0;
  178. // if (contrast < 0) {
  179. // scale = (100 - contrast) / 100.0;
  180. // } else if (contrast > 0) {
  181. // scale = contrast / 100.0 * 2.5 + 1;
  182. // }
  183. // if (contrast < 50) {
  184. // scale = contrast / 50.0;
  185. // } else if (contrast > 50) {
  186. // scale = (contrast - 50) / 50.0 * 2.5 + 1;
  187. // }
  188. double lum = brightness.toDouble();
  189. double contrast = this.contrast.toDouble();
  190. if (contrast < -100) contrast = -100;
  191. if (contrast > 100) contrast = 100;
  192. contrast = (100.0 + contrast) / 100.0;
  193. contrast *= contrast;
  194. // print(contrast);
  195. print(lum);
  196. scale = contrast;
  197. // scale != 1.0 ? brightness * (1.0 - scale) : brightness.toDouble();
  198. // _paint.colorFilter = ui.ColorFilter.matrix(<double>[
  199. // scale, 0, 0, 0, lum, // R
  200. // 0, scale, 0, 0, lum, // G
  201. // 0, 0, scale, 0, lum, // B
  202. // 0, 0, 0, 1, 0, // A
  203. // ]);
  204. _paint.colorFilter = ui.ColorFilter.mode(Colors.blue, BlendMode.darken);
  205. final centerW = size.width / 2;
  206. final centerH = size.height / 2;
  207. canvas.translate(centerW, centerH);
  208. final offset = ui.Offset(-centerW, -centerH);
  209. canvas.drawImage(image, offset, _paint);
  210. }
  211. @override
  212. bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
  213. }