Flutter로 5분 안에 Instagram 스타일 ‘Shot on Canon’ UI 구축하기
Source: Dev.to
Overview
소셜 미디어 클론, 부동산 앱, 혹은 사진 포트폴리오를 Flutter로 만들고 있다면, 메타데이터를 표시하는 것만으로도 UI에 큰 완성도를 더할 수 있습니다.
사용자들은 멋진 사진 뒤에 숨은 하드웨어 사양을 보는 것을 좋아합니다(예: Shot on Canon | ISO 400 | 1/200s).
Dart에서 무거운 이미지 파일(특히 .CR2 같은 RAW 포맷)로부터 EXIF 데이터를 직접 추출하면 메모리 사용량이 크게 늘어나고 앱이 종종 크래시됩니다. 또한 그런 대용량 파일을 바로 데이터베이스에 업로드하면 클라우드 스토리지 비용이 급증합니다.
가장 깔끔한 아키텍처는 메타데이터 추출과 이미지 압축을 마이크로서비스에 위임하는 것입니다. 아래는 PicTalk API를 이용해 5분 안에 이를 구현하는 간단한 방법입니다.
Prerequisites
- Free API key – PicTalk RapidAPI 페이지에서 발급받으세요.
pubspec.yaml에http패키지를 추가합니다:
dependencies:
http: ^1.1.0
Sending the Image to PicTalk
Flutter UI가 멈추지 않도록 MultipartRequest를 사용해 이미지 파일을 스트리밍합니다.
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:io';
Future?> processImage(File imageFile) async {
final uri = Uri.parse('https://pictalk-image-processing.p.rapidapi.com/extract');
final request = http.MultipartRequest('POST', uri);
// Add your RapidAPI key
request.headers.addAll({
'x-rapidapi-key': 'YOUR_RAPIDAPI_KEY_HERE',
'x-rapidapi-host': 'pictalk-image-processing.p.rapidapi.com',
});
final multipartFile = await http.MultipartFile.fromPath('image_file', imageFile.path);
request.files.add(multipartFile);
final streamedResponse = await request.send();
final response = await http.Response.fromStream(streamedResponse);
if (response.statusCode == 200) {
return jsonDecode(response.body); // Returns the CDN URL and EXIF data
}
return null;
}
API가 반환하는 내용:
image_url– CDN에 호스팅된 가벼운 WebP 이미지.camera_make,iso,shutter_speed등 – 추출된 EXIF 메타데이터.
Rendering the Instagram‑Style Tag
응답 데이터를 받아오면 압축된 이미지와 깔끔한 하드웨어 태그를 표시하는 것은 매우 간단합니다.
// Assuming `responseData` is the Map returned from `processImage`
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 1. Show the compressed, fast‑loading WebP image
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.network(responseData['image_url']),
),
const SizedBox(height: 8),
// 2. Show the hardware tag
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: Colors.grey.shade200,
borderRadius: BorderRadius.circular(20),
),
child: Text(
'Shot on ${responseData['camera_make']} | ISO ${responseData['iso']} | ${responseData['shutter_speed']}s',
style: const TextStyle(
fontWeight: FontWeight.w500,
color: Colors.black87,
),
),
),
],
);
Summary
- PicTalk API를 사용해 EXIF 추출과 이미지 압축을 오프로드합니다.
http.MultipartRequest로 이미지를 스트리밍해 UI가 응답성을 유지하도록 합니다.- 반환된 WebP 이미지와 메타데이터를 컴팩트한 Instagram 스타일 태그로 렌더링합니다.
이 방법을 통해 무거운 네이티브 파싱을 없애고 스토리지 비용을 절감하며, 사진 중심의 Flutter 앱에 전문적인 마무리를 더할 수 있습니다.