Flutter图片URL处理插件flutter_sanity_image_url的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter图片URL处理插件flutter_sanity_image_url的使用

描述

flutter_sanity_image_url 是一个用于快速生成Sanity图像URL的Dart包,移植自sanity-io/image-url。它旨在与flutter_sanity package一起使用,以实现内容编辑者指定裁剪和热点,并在应用中创建正确的URL来尊重这些设置。此外,它还支持应用图像变换(如设置宽度和高度),并提供从Sanity解析图像数据的方法。

特性

  • 支持编辑者指定裁剪和热点,确保这些设置在应用程序中得到尊重。
  • 可以通过ImageUrlBuilder设置图像的宽度和高度等变换。
  • 提供了SanityImage.fromJson()方法,该方法可以解析来自Sanity的图像数据为对象,包含所有数据和元数据类型:
    • 访问图像的颜色调色板,以基于图像进行更好的样式设计。
    • 使用lqip实现低分辨率图像占位符。

开始使用

首先,在项目中添加依赖:

dart pub add flutter_sanity flutter_sanity_image_url

然后在代码中导入必要的库并初始化:

import 'package:flutter/material.dart';
import 'package:flutter_sanity/flutter_sanity.dart';
import 'package:flutter_sanity_image_url/flutter_sanity_image_url.dart';

final sanityClient = SanityClient(projectId: "your_project_id", dataset: "your_dataset");

示例代码

以下是一个完整的示例,展示了如何使用flutter_sanity_image_url插件展示图像、访问颜色调色板以及应用图像变换。

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_sanity/flutter_sanity.dart';
import 'package:flutter_sanity_image_url/flutter_sanity_image_url.dart';
import 'package:sanity_image_app/sanity_image.dart';

// 初始化Sanity客户端
final sanityClient = SanityClient(projectId: "gua6su5h", dataset: "production");

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sanity Image Url Demo',
      theme: ThemeData(
        primarySwatch: Colors.lightBlue,
      ),
      home: const MyHomePage(title: 'Sanity Image Url Demo'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  // 定义获取图像的方法
  Future<dynamic> fetchImage() async {
    var query =
        r"*[_type=='post'][0..2]{..., 'img': {'image': mainImage, 'asset': mainImage.asset->}}";
    var res = await sanityClient.fetch(query);
    return Future.value(res);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
        titleTextStyle: const TextStyle(
          color: Colors.white,
          fontSize: 20,
          fontWeight: FontWeight.bold,
        ),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: [
            Expanded(
              child: FutureBuilder(
                future: fetchImage(),
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.done) {
                    if (snapshot.hasError) {
                      return Center(child: ErrorWidget(snapshot.error!));
                    }

                    if (snapshot.hasData) {
                      var posts = snapshot.data as List;
                      var pictures = posts.map((e) => SanityImage.fromJson(e["img"])).toList();

                      return ListView(
                        shrinkWrap: true,
                        padding: const EdgeInsets.all(2.0),
                        children: [
                          const SizedBox(height: 15),
                          const Text(
                            "Examples:",
                            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
                          ),
                          const SizedBox(height: 10),
                          RichText(
                            text: TextSpan(
                              text: "This example app is built to showcase the functionality of ",
                              style: TextStyle(color: Colors.blueGrey[500]),
                              children: [
                                TextSpan(
                                  text: "flutter_sanity_image",
                                  style: TextStyle(fontWeight: FontWeight.w500),
                                ),
                                const TextSpan(text: " package developed by Techurve with ❤️"),
                              ],
                            ),
                          ),
                          const SizedBox(height: 40),
                          const Text("I. Use of Sanity Color Palette:", style: TextStyle(fontWeight: FontWeight.bold)),
                          const SizedBox(height: 10),
                          const Text("a. Apply Background Overlay"),
                          const SizedBox(height: 10),
                          Container(
                            padding: const EdgeInsets.fromLTRB(0, 10, 0, 10),
                            width: 320.0,
                            height: 180.0,
                            decoration: BoxDecoration(
                              image: DecorationImage(
                                image: NetworkImage(urlFor(pictures[0]).url()),
                                fit: BoxFit.cover,
                                colorFilter: ColorFilter.mode(
                                  pictures[0].palette?.darkMuted.background.withOpacity(0.5) ?? Colors.black.withOpacity(0.2),
                                  BlendMode.darken,
                                ),
                              ),
                            ),
                            child: Center(
                              child: Text(
                                posts[0]["title"],
                                style: TextStyle(
                                  fontSize: 26,
                                  color: pictures[0].palette?.dominant.title,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ),
                          ),
                          const SizedBox(height: 10),
                          Container(
                            width: 320.0,
                            height: 180.0,
                            decoration: BoxDecoration(
                              image: DecorationImage(
                                image: NetworkImage(urlFor(pictures[1]).url()),
                                fit: BoxFit.cover,
                                colorFilter: ColorFilter.mode(
                                  pictures[1].palette?.dominant.background.withOpacity(0.5) ?? Colors.black.withOpacity(0.2),
                                  BlendMode.darken,
                                ),
                              ),
                            ),
                            child: Center(
                              child: Text(
                                posts[1]["title"],
                                style: TextStyle(
                                  fontSize: 26,
                                  color: pictures[1].palette?.dominant.title,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ),
                          ),
                          const SizedBox(height: 20),
                          const Text("b. Style Text based on Image Colors"),
                          const SizedBox(height: 10),
                          Column(
                            children: [
                              Container(
                                width: 320.0,
                                height: 180.0,
                                decoration: BoxDecoration(
                                  image: DecorationImage(
                                    image: NetworkImage(urlFor(pictures[1]).url()),
                                    fit: BoxFit.cover,
                                  ),
                                ),
                              ),
                              const SizedBox(height: 5),
                              Text(
                                posts[1]["title"],
                                style: TextStyle(
                                  fontSize: 26,
                                  color: pictures[1].palette?.dominant.background,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ],
                          ),
                          const SizedBox(height: 40),
                          const Text("II. Placeholder Image for Loading:", style: TextStyle(fontWeight: FontWeight.bold)),
                          const SizedBox(height: 10),
                          CachedNetworkImage(
                            imageUrl: urlFor(pictures[0]).size(400, 400).url(),
                            placeholder: (context, url) => ImagePlaceholder(lqip: pictures[0].lqip),
                          ),
                          const SizedBox(height: 40),
                          const Text("III. Image Transformations:", style: TextStyle(fontWeight: FontWeight.bold)),
                          const SizedBox(height: 40),
                          const Text("a. size = 200 x 200"),
                          const SizedBox(height: 10),
                          Image.network(urlFor(pictures[1]).size(200, 200).url()),
                          const SizedBox(height: 10),
                          const Text("b. blur = 50"),
                          const SizedBox(height: 10),
                          Image.network(urlFor(pictures[1]).blur(50).url()),
                          const SizedBox(height: 10),
                          const Text("c. cropped"),
                          const SizedBox(height: 10),
                          Image.network(urlFor(pictures[0]).rect(200, 200, 400, 400).url()),
                          const SizedBox(height: 10),
                          const Text("d. flipped horizontally"),
                          const SizedBox(height: 10),
                          Image.network(urlFor(pictures[1]).flipHorizontal().url()),
                          const SizedBox(height: 10),
                          const Text("e. flipped vertically"),
                          const SizedBox(height: 10),
                          Image.network(urlFor(pictures[1]).flipVertical().url()),
                        ],
                      );
                    }
                  }

                  return const Center(child: CircularProgressIndicator());
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

关键点解释

  1. 创建ImageUrlBuilder实例:使用sanityClient创建一个ImageUrlBuilder实例,以便在整个应用程序中使用。

    final builder = ImageUrlBuilder(sanityClient);
    
  2. 使用ImageUrlBuilder构建URL:通过链式调用ImageUrlBuilder的方法来添加选项,并最终调用url()获取实际的图像URL。

    Image.network(urlFor(image).size(200, 200).url())
    
  3. 访问颜色调色板:可以通过SanityImage对象访问图像的颜色调色板属性,如darkMutedlightVibrant等。

    print(myImage.palette?.darkMuted.background);
    
  4. 使用LQIP:可以通过提供的ImagePlaceholder小部件或直接访问lqip属性来实现低分辨率图像占位符。

    CachedNetworkImage(
      imageUrl: urlFor(pictures[0]).size(400, 400).url(),
      placeholder: (context, url) => ImagePlaceholder(lqip: pictures[0].lqip),
    )
    

这个示例展示了如何使用flutter_sanity_image_url插件来处理图像URL,包括显示图像、访问颜色调色板、应用图像变换以及使用低质量图像预览(LQIP)。希望这个例子能帮助你更好地理解和使用这个插件。


更多关于Flutter图片URL处理插件flutter_sanity_image_url的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图片URL处理插件flutter_sanity_image_url的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 flutter_sanity_image_url 插件的示例代码。这个插件通常用于处理与Sanity CMS(一个headless CMS)集成的图片URL。假设你已经将 flutter_sanity_image_url 插件添加到了你的 pubspec.yaml 文件中,并且已经运行了 flutter pub get

1. 添加依赖

首先,确保你的 pubspec.yaml 文件中有以下依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_sanity_image_url: ^latest_version # 请替换为最新的版本号

2. 导入插件

在你的 Dart 文件中导入插件:

import 'package:flutter_sanity_image_url/flutter_sanity_image_url.dart';

3. 使用插件处理图片URL

假设你有一个从Sanity CMS获取的图片对象,它通常包含一个 _ref_type 字段,以及可能的 assetmetadata 字段。你可以使用 SanityImageUrlBuilder 来构建图片的URL。

以下是一个示例代码,展示如何使用 flutter_sanity_image_url 来处理图片URL:

import 'package:flutter/material.dart';
import 'package:flutter_sanity_image_url/flutter_sanity_image_url.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('FlutterSanityImageUrl Example'),
        ),
        body: Center(
          child: ImageFromSanity(
            imageRef: {
              '_ref': 'your-image-reference-here', // 替换为你的图片引用
              '_type': 'image',
            },
            projectId: 'your-sanity-project-id', // 替换为你的Sanity项目ID
            dataset: 'your-dataset-name', // 替换为你的数据集名称
            width: 800, // 想要的图片宽度
            height: 600, // 想要的图片高度
          ),
        ),
      ),
    );
  }
}

class ImageFromSanity extends StatelessWidget {
  final Map<String, String> imageRef;
  final String projectId;
  final String dataset;
  final int width;
  final int height;

  ImageFromSanity({
    required this.imageRef,
    required this.projectId,
    required this.dataset,
    required this.width,
    required this.height,
  });

  @override
  Widget build(BuildContext context) {
    final imageUrl = SanityImageUrlBuilder()
        .projectId(projectId)
        .dataset(dataset)
        .image(imageRef)
        .width(width)
        .height(height)
        .auto('format') // 自动选择最佳格式
        .build();

    return Image.network(imageUrl);
  }
}

解释

  1. 导入必要的包:首先导入 flutter_sanity_image_url 包。
  2. 定义主应用:在 MyApp 类中,我们定义了一个简单的 Flutter 应用,包含一个 Scaffold 和一个 Center 组件,中心位置放置了一个 ImageFromSanity 组件。
  3. 定义 ImageFromSanity 组件:这个组件接受图片引用、项目ID、数据集名称、宽度和高度作为参数。它使用 SanityImageUrlBuilder 来构建图片的URL,并将这个URL传递给 Image.network 组件来显示图片。

请确保将示例代码中的占位符(如 your-image-reference-hereyour-sanity-project-idyour-dataset-name)替换为你自己的Sanity CMS配置和图片引用。

这样,你就可以在你的Flutter应用中处理和显示来自Sanity CMS的图片了。

回到顶部