在 Flutter 中从 sharedPreferences 加载图像到 pdf

Load image from sharedPreferences to pdf in Flutter

我需要将图像从 sharedPreferences 加载到 pdf 文档。 图像在正常使用时正常加载,但我不知道如何在 pdf 中加载它。 当我尝试像普通图像一样加载它时,我得到“未处理的异常:类型 'Image' 不是类型 'PdfImage' 的子类型”

我平时就是这样使用的

import 'package:flutter/material.dart';
import 'package:flutter_settings_screens/flutter_settings_screens.dart';
import 'package:image_picker/image_picker.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:MyApp/SharedPrefUtility.dart';

Future<void> initSettings() async {
  await Settings.init(
    cacheProvider: SharePreferenceCache(),
  );
}

class ProfilePage extends StatefulWidget {
  @override
  _ProfilePageState createState() => _ProfilePageState();
}

class _ProfilePageState extends State<ProfilePage> {
  Image logo;

  pickImage(ImageSource source) async {
    final _image = await ImagePicker.pickImage(source: ImageSource.gallery);

    if (_image != null) {
      setState(() {
        logo = Image.file(_image);
      });
      ImageSharedPrefs.saveImageToPrefs(
          ImageSharedPrefs.base64String(_image.readAsBytesSync()));
    } else {
      print('Error picking image!');
    }
  }

  loadImageFromPrefs() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    final imageKeyValue = prefs.getString(IMAGE_KEY);
    if (imageKeyValue != null) {
      final imageString = await ImageSharedPrefs.loadImageFromPrefs();
      setState(() {
        logo = ImageSharedPrefs.imageFrom64BaseString(imageString);
      });
    }
  }

  @override
  void initState() {
    super.initState();
    loadImageFromPrefs();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.red,
        title: Text('Profile Settings'),
      ),
      body: Center(
        child: ListView(
          children: [
            Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                ClipRect(
                  child: Container(
                    width: 300,
                    height: 300,
                    child: logo == null ? Text('No image selected.') : logo,
                  ),
                ),
                RaisedButton(
                  onPressed: () {
                    pickImage(ImageSource.gallery);
                  },
                  child: Text('Pick Company Logo'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

和SharedPrefUtility.dart

import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/widgets.dart';
import 'package:shared_preferences/shared_preferences.dart';

const IMAGE_KEY = 'IMAGE_KEY';

class ImageSharedPrefs {
  static Future<bool> saveImageToPrefs(String value) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    return await prefs.setString(IMAGE_KEY, value);
  }


  static Future<String> loadImageFromPrefs() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.getString(IMAGE_KEY);
  }

  static String base64String(Uint8List data) {
    return base64Encode(data);
  }

  static imageFrom64BaseString(String base64String) {
    return Image.memory(
      base64Decode(base64String),
      fit: BoxFit.contain,
    );
  }
}

任何建议都很好。

“未处理的异常:类型 'Image' 不是类型 'PdfImage'”的子类型“ - 它说您需要转换 Image PdfImage

import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart ' as pw;

pdf = pw.Document();
PdfImage pdfImage = PdfImage.fromImage(pdf.document, image: logo);

pdf.addPage(
  pw.Page(
    pageFormat: PdfPageFormat.a4,
    build: (context) {
      return pw.Image(arcPdfImage, fit: pw.BoxFit.contain);
    },
  ),
);

我正在使用从我的资产中获取的图像以这种方式创建 PDF:

PdfImage _logo = PdfImage.file(
    doc.document,
    bytes: (await rootBundle.load('assets/client-logo.png')).buffer.asUint8List(),
  );

//later, during widget tree creation 
pw.Image(_logo, width: 180); 
         

这不完全是你在做什么,但我认为它已经足够接近了。 PdfImage class 可以将任何 Uint8List 作为 bytes 参数的输入,因此您应该能够使用与为 [=13] 定义的 base64String 方法相同的输入=]

davey06 在 gitHub

上给出了答案
   final imageString = await ImageSharedPrefs.loadImageFromPrefs(); 
// Create a PDF document.
final document = pw.Document();

// Add page to the PDF
document.addPage(pw.Page(build: (context) {
  return pw.Center(
    child: pw.Image(
      PdfImage.file(document.document, bytes: base64Decode(imageString)),
    ),
  );
}));

// Return the PDF file content
return document.save();

https://github.com/DavBfr/dart_pdf/issues/477