🌵

iPhone端末で、背景が透過した画像を、思ったように表示できない話

2021/11/25に公開

目次

1.早速結論。
2.他のやり方を試す。

1.早速結論

同じ悩みで、時間を浪費することのないように、記事にします。

内容は、ImagePickerでiPhoneのgalleryから、背景が透過した画像を色付きのContainerのchildに配置しても、背景が透過されず、白くなってしまう問題です。

いろいろ試行錯誤したのですが、

vimeoのヘルプページが参考になりました。(早くこの記事に出会っていれば...)

結論: iOSバージョン13以降を搭載したiOSデバイス(iPhone/iPad)は、透明な背景に対応しておりません。その結果、画像は白い背景で表示されます。

https://vimeo.zendesk.com/hc/ja/articles/360057547772-iOSで画像の背景を白から透明に変更する

回避する手順をユーザーに促しても、ストレスに感じると思うので、私はiphoneのGalleryから取ってくるのを諦め、他のやり方にしました。

2.他のやり方を試す

Image.assetとImage.networkで画像を表示して、透過されるかを載せておきます。
アザラシとシマウマの画像で試します。

結果

アザラシ:

シマウマ:

Image.assetsとImage.networkは、画像が透過されるの確認できました。

が、ImagePickerではなぜかアザラシは透過し、シマウマは透過しませんでした。原因は全くわかりません。

最後に

全コードを記載しておきます。

main.dart
import 'dart:io';

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

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  File? _image;
  final picker = ImagePicker();

  Future getImageFromGallery() async {
    final pickedFile = await picker.pickImage(source: ImageSource.gallery);

    if (pickedFile != null) {
      _image = File(pickedFile.path);
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('test'),
        ),
        body: Align(
          alignment: Alignment.center,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Container(
                    height: 200,
                    width: 200,
                    color: Colors.blue,
                    child: Image.asset('images/shimauma-removebg-preview.png'),
                  ),
                  const Text(
                    'Image.assets',
                    style: TextStyle(fontSize: 24),
                  ),
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Container(
                    height: 200,
                    width: 200,
                    color: Colors.blue,
                    child: Image.network(
                        'https://storage.googleapis.com/zenn-user-upload/634146df9346-20211125.png'),
                  ),
                  const Text(
                    'Image.network',
                    style: TextStyle(fontSize: 24),
                  ),
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Container(
                    height: 200,
                    width: 200,
                    color: Colors.blue,
                    child: _image != null
                        ? Image.file(
                            _image!,
                          )
                        : null,
                  ),
                  InkWell(
                    onTap: () async {
                      await getImageFromGallery();
                    },
                    child: const Text(
                      'ImagePicker',
                      style: TextStyle(fontSize: 24),
                    ),
                  ),
                ],
              ),
            ],
          ),
        ));
    // This trailing comma makes auto-formatting nicer for build methods.
  }
}

Discussion