首页 > 解决方案 > Flutter - 调整网络图像大小

问题描述

有没有一种方法可以调整图像的大小而无需事先将其写入存储?我正在使用一个 pdf 库,图像需要它的字节。

我所做的是使用 http.get 获取图像,然后获取字节以将其放入 pdf 中。问题是我需要在将图像放入 pdf 之前调整其大小。

我唯一拥有的是图像的 url 或 uint8list

Response response = await http.get(imageUrl);
Uint8List imgBytes = response.bodyBytes;

之后:

Image(
    PdfImage.file(pdf.document,
    bytes: imageBytes)
),

我使用的 Pdf 库:https ://pub.dev/packages/pdf

标签: flutterpdfdart

解决方案


您可以在下面复制粘贴运行完整代码
您可以使用ui.instantiateImageCodec并指定targetHeight并且targetWidth
您可以看到调整大小后输出图像尺寸变小

代码片段

    String imageUrl = 'https://picsum.photos/250?image=9';
    http.Response response = await http.get(imageUrl);
    originalUnit8List = response.bodyBytes;

    ui.Image originalUiImage = await decodeImageFromList(originalUnit8List);
    ByteData originalByteData = await originalUiImage.toByteData();
    print('original image ByteData size is ${originalByteData.lengthInBytes}');

    var codec = await ui.instantiateImageCodec(originalUnit8List,
        targetHeight: 50, targetWidth: 50);
    var frameInfo = await codec.getNextFrame();
    ui.Image targetUiImage = frameInfo.image;

    ByteData targetByteData =
        await targetUiImage.toByteData(format: ui.ImageByteFormat.png);
    print('target image ByteData size is ${targetByteData.lengthInBytes}');
    targetlUinit8List = targetByteData.buffer.asUint8List();

工作演示的输出

I/flutter (17023): original image ByteData size is 250000
I/flutter (17023): target image ByteData size is 4060

工作演示

在此处输入图像描述

完整代码

import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:io';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Uint8List targetlUinit8List;
  Uint8List originalUnit8List;

  void _resizeImage() async {
    String imageUrl = 'https://picsum.photos/250?image=9';
    http.Response response = await http.get(imageUrl);
    originalUnit8List = response.bodyBytes;

    ui.Image originalUiImage = await decodeImageFromList(originalUnit8List);
    ByteData originalByteData = await originalUiImage.toByteData();
    print('original image ByteData size is ${originalByteData.lengthInBytes}');

    var codec = await ui.instantiateImageCodec(originalUnit8List,
        targetHeight: 50, targetWidth: 50);
    var frameInfo = await codec.getNextFrame();
    ui.Image targetUiImage = frameInfo.image;

    ByteData targetByteData =
        await targetUiImage.toByteData(format: ui.ImageByteFormat.png);
    print('target image ByteData size is ${targetByteData.lengthInBytes}');
    targetlUinit8List = targetByteData.buffer.asUint8List();

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            originalUnit8List == null
                ? Container()
                : Image.memory(originalUnit8List),
            targetlUinit8List == null
                ? Container()
                : Image.memory(targetlUinit8List),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _resizeImage,
        tooltip: 'Resize',
        child: Icon(Icons.add),
      ),
    );
  }
}

推荐阅读