0% found this document useful (0 votes)
11 views7 pages

Image Upload for Prescriptions

The document contains a Flutter widget called ImageInput that allows users to pick and display an image, specifically for uploading a prescription image. It includes functionality for selecting images from the gallery or camera, error handling for image selection, and a preview of the selected image with an option to edit. The widget is styled with various UI elements and uses packages like image_picker and path_provider for image handling.

Uploaded by

Alaise Tchindou
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views7 pages

Image Upload for Prescriptions

The document contains a Flutter widget called ImageInput that allows users to pick and display an image, specifically for uploading a prescription image. It includes functionality for selecting images from the gallery or camera, error handling for image selection, and a preview of the selected image with an option to edit. The widget is styled with various UI elements and uses packages like image_picker and path_provider for image handling.

Uploaded by

Alaise Tchindou
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

import 'package:figma_squircle/figma_squircle.

dart';
import 'package:flutter/[Link]';
import 'package:gap/[Link]';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
import 'package:go_router/go_router.dart';
import 'package:chap_sante/utils/[Link]';

class ImageInput extends StatefulWidget {


const ImageInput({[Link]});

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

class _ImageInputState extends State<ImageInput> {


File? _image;
final ImagePicker _picker = ImagePicker();

Future<void> _pickImage(ImageSource source) async {


try {
final XFile? pickedFile = await _picker.pickImage(source: source);
if (pickedFile != null) {
final directory = await getApplicationDocumentsDirectory();
final String path = [Link];
final String newPath = '$path/$
{[Link]().millisecondsSinceEpoch}.png';

// Supprime l'ancienne image si elle existe


if (_image != null) {
await _image!.delete();
}

// Sauvegarde la nouvelle image


final File newImage = await File([Link]).copy(newPath);
setState(() {
_image = newImage;
});
}
} catch (e) {
// Gestion des erreurs éventuelles
[Link](context).showSnackBar(
SnackBar(content: Text('Erreur lors de la sélection de l\'image : $e')),
);
}
}

@override
Widget build(BuildContext context) {
return Container(
padding: const [Link](defaultSpacing),
decoration: BoxDecoration(
borderRadius: [Link](defaultRadius),
),
child: Column(
mainAxisSize: [Link],
children: [
Row(
mainAxisAlignment: [Link],
children: [
Text(
"Image de l'ordonnance",
style: [Link](fontWeight: [Link]),
),
Row(
children: [
const Icon(
Icons.info_outline,
size: defaultIconSize / 2,
color: darkBlue,
),
Text(
" info",
style: [Link](color: darkBlue),
),
],
)
],
),
const Gap(defaultSpacing),
GestureDetector(
onTap: () => _showPicker(context),
child: Container(
height: [Link](context) * 0.15,
width: [Link](context) * 0.96,
decoration: ShapeDecoration(
color: [Link](0.1),
shape: SmoothRectangleBorder(
side: const BorderSide(
color: lightGrey,
width: 1,
),
borderRadius: SmoothBorderRadius(
cornerRadius: defaultRadius,
cornerSmoothing: 1,
),
),
),
child: Stack(
children: [
_image != null ? _buildPreview() : _buildUploadPrompt(),
if (_image != null)
Container(
height: [Link](context).[Link] * 0.2,
width: [Link](context).[Link] * 0.96,
decoration: BoxDecoration(
borderRadius: [Link](10.0),
gradient: LinearGradient(
begin: [Link],
end: [Link],
colors: [
[Link](0.5),
[Link](0.3),
[Link](0.1),
],
),
),
),
if (_image != null) _buildEditButton(),
],
),
),
),
],
),
);
}

void _showPicker(BuildContext context) {


showModalBottomSheet(
context: context,
builder: (BuildContext bc) {
return SafeArea(
child: Wrap(
children: <Widget>[
ListTile(
leading: const Icon(Icons.photo_library),
title: const Text('Gallerie'),
onTap: () {
[Link](context); // Fermez le BottomSheet avant de prendre
la photo
_pickImage([Link]);
},
),
ListTile(
leading: const Icon(Icons.photo_camera),
title: const Text('Camera'),
onTap: () {
[Link](context); // Fermez le BottomSheet avant de prendre
la photo
_pickImage([Link]);
},
),
],
),
);
},
);
}

Widget _buildUploadPrompt() {
return Center(
child: Column(
mainAxisAlignment: [Link],
children: [
const Icon(
[Link],
color: lightGrey,
size: 50,
),
const SizedBox(height: 10),
Text(
"Cliquez pour ajouter une image de l'ordonnance",
style: TextStyle(color: [Link][700], fontSize: 16),
),
],
),
);
}

Widget _buildPreview() {
return Center(
child: [Link](
_image!,
fit: [Link],
),
);
}

Widget _buildEditButton() {
return Positioned(
bottom: 10,
right: 10,
child: InkWell(
onTap: () => _showPicker(context),
child: Row(
children: [
const Icon([Link], color: errorColor, size: defaultIconSize),
const SizedBox(width: 5),
Text(
'Modifier',
style: [Link](color: errorColor),
),
],
),
),
);
}
}

// import 'package:figma_squircle/figma_squircle.dart';
// import 'package:flutter/[Link]';
// import 'package:gap/[Link]';
// import 'package:image_picker/image_picker.dart';
// import 'dart:io';
// import 'package:go_router/go_router.dart';
// import 'package:chap_sante/utils/[Link]';
//
// class ImageInput extends StatefulWidget {
// const ImageInput({[Link]});
//
// @override
// _ImageInputState createState() => _ImageInputState();
// }
//
// class _ImageInputState extends State<ImageInput> {
// File? _image;
// final ImagePicker _picker = ImagePicker();
//
// Future<void> _pickImage(ImageSource source) async {
// try {
// final XFile? pickedFile = await _picker.pickImage(source: source);
// if (pickedFile != null) {
// setState(() {
// _image = File([Link]);
// });
// }
// } catch (e) {
// // Gestion des erreurs éventuelles
// [Link](context).showSnackBar(
// SnackBar(content: Text('Erreur lors de la sélection de l\'image : $e')),
// );
// }
// }
//
// @override
// Widget build(BuildContext context) {
// return Container(
// padding: const [Link](defaultSpacing),
// decoration: BoxDecoration(
// borderRadius: [Link](defaultRadius),
// ),
// child: Column(
// mainAxisSize: [Link],
// children: [
// Row(
// mainAxisAlignment: [Link],
// children: [
// Text(
// "Image de l'ordonnance",
// style: [Link](fontWeight: [Link]),
// ),
// Row(
// children: [
// const Icon(
// Icons.info_outline,
// size: defaultIconSize / 2,
// color: darkBlue,
// ),
// Text(
// " info",
// style: [Link](color: darkBlue),
// ),
// ],
// )
// ],
// ),
// const Gap(defaultSpacing),
// GestureDetector(
// onTap: () => _showPicker(context),
// child: Container(
// height: [Link](context) * 0.15,
// width: [Link](context) * 0.96,
// decoration: ShapeDecoration(
// color: [Link](0.1),
// shape: SmoothRectangleBorder(
// side: const BorderSide(
// color: lightGrey,
// width: 1,
// ),
// borderRadius: SmoothBorderRadius(
// cornerRadius: defaultRadius,
// cornerSmoothing: 1,
// ),
// ),
// ),
// child: Stack(
// children: [
// _image != null ? _buildPreview() : _buildUploadPrompt(),
// if (_image != null)
// Container(
// height: [Link](context).[Link] * 0.2,
// width: [Link](context).[Link] * 0.96,
// decoration: BoxDecoration(
// borderRadius: [Link](10.0),
// gradient: LinearGradient(
// begin: [Link],
// end: [Link],
// colors: [
// [Link](0.5),
// [Link](0.3),
// [Link](0.1),
// ],
// ),
// ),
// ),
// if (_image != null) _buildEditButton(),
// ],
// ),
// ),
// ),
// ],
// ),
// );
// }
//
// void _showPicker(BuildContext context) {
// showModalBottomSheet(
// context: context,
// builder: (BuildContext bc) {
// return SafeArea(
// child: Wrap(
// children: <Widget>[
// ListTile(
// leading: const Icon(Icons.photo_library),
// title: const Text('Gallerie'),
// onTap: () {
// [Link](context); // Fermez le BottomSheet avant de
prendre la photo
// _pickImage([Link]);
// },
// ),
// ListTile(
// leading: const Icon(Icons.photo_camera),
// title: const Text('Camera'),
// onTap: () {
// [Link](context); // Fermez le BottomSheet avant de
prendre la photo
// _pickImage([Link]);
// },
// ),
// ],
// ),
// );
// },
// );
// }
//
// Widget _buildUploadPrompt() {
// return Center(
// child: Column(
// mainAxisAlignment: [Link],
// children: [
// const Icon(
// [Link],
// color: lightGrey,
// size: 50,
// ),
// const SizedBox(height: 10),
// Text(
// "Cliquez pour ajouter une image de l'ordonnance",
// style: TextStyle(color: [Link][700], fontSize: 16),
// ),
// ],
// ),
// );
// }
//
// Widget _buildPreview() {
// return Center(
// child: [Link](
// _image!,
// fit: [Link],
// ),
// );
// }
//
// Widget _buildEditButton() {
// return Positioned(
// bottom: 10,
// right: 10,
// child: InkWell(
// onTap: () => _showPicker(context),
// child: Row(
// children: [
// const Icon([Link], color: errorColor, size: defaultIconSize),
// const SizedBox(width: 5),
// Text(
// 'Modifier',
// style: [Link](color: errorColor),
// ),
// ],
// ),
// ),
// );
// }
// }

Common questions

Powered by AI

The ImageInput widget offers functionalities for selecting and displaying images of prescriptions. It uses the ImagePicker to allow users to pick images from their gallery or camera. The picked image is then saved in the application's documents directory and displayed in a preview area on the widget. It also provides an interface for users to edit the selected image by re-selecting an image from the image source options .

Error handling is implemented using a try-catch block when picking an image. If an exception occurs, a SnackBar is displayed with an error message to inform the user that an error has happened during image selection. This approach enhances user interaction by providing immediate feedback about the failure and maintains user trust by clearly communicating issues without crashing the app .

The _buildPreview function displays the selected image within the specified area in the widget. It works alongside the stack of components inside the GestureDetector to provide a seamless transition from image selection to display. If an image is present, the function renders the image in the assigned area, covered by a gradient overlay effect for enhanced visual focus. This seamless integration of components enhances the image upload experience by offering immediate visual feedback of the uploaded content .

The Future<void> return type indicates that the _pickImage function is asynchronous and will complete its execution at an unspecified future time. By using this return type, the function can perform time-consuming operations such as accessing device storage or camera without blocking the main UI thread. This contributes to responsive UI performance in Flutter by allowing the app to handle other tasks concurrently, thus enhancing user experience and preventing the app from freezing during long operations .

The _pickImage function stores images by first selecting an image and then copying it to the application's documents directory with a new filename based on the current timestamp. This method ensures that each image is uniquely identifiable and avoids overwriting existing files. By managing images in the application's local directory instead of keeping them in temporary storage, it optimizes performance by reducing the need to repeatedly fetch images from external sources, thereby speeding up access times and conserving resources .

Visual hierarchy in the ImageInput widget is achieved through the use of text styles, icon sizes, and layout structure. Text such as 'Image de l'ordonnance' is styled with bold fonts to stand out as the main heading. Icons and text within rows are appropriately sized and colored, such as using dark blue for information text, providing visual clarity. This design practice is crucial as it helps users quickly identify and understand the focus and function of interface elements, guiding them efficiently through the interaction process .

State management in the ImageInput widget is managed using a StatefulWidget, with the state encapsulated in the _ImageInputState class. Whenever the image selection changes, the setState() method is called, which updates the UI by re-building the widget with the new state. This mechanism allows for real-time updates to the UI without necessitating a full rebuild of the entire widget tree, ensuring efficiency and responsiveness .

showModalBottomSheet in the ImageInput class provides a modal interface that slides up from the bottom of the screen to present image source options. It enhances user interaction flow by keeping the user within the same screen while offering additional functionality, such as choosing between a gallery or camera for image selection. This strategy minimizes navigation away from the current interface, maintaining context and reducing the cognitive load on the user, thus promoting a smoother and more intuitive workflow .

Using SmoothRectangleBorder from the figma_squircle package provides a design aesthetic with smoothly rounded corners, which can contribute to creating a modern and polished visual style. Advantages include a distinctive look that can differentiate an application from others using standard rectangular forms, potentially boosting user engagement through a more appealing interface. This approach also allows designers to incorporate incremental creative elements in their design, which is important to maintain brand consistency and enhance overall aesthetic appeal .

The GestureDetector widget in the ImageInput's build method wraps a Container that triggers image selection. This widget enables touch event detection on its child widget, allowing users to tap on the container to initiate the _showPicker function. This interactivity improves usability by making it intuitive for users to perform actions, such as selecting images, through a straightforward tap gesture .

You might also like