Gereksinimler ve Ön Hazırlık
Uygulamanızı geliştirmeye başlamadan önce sisteminizde Flutter 3.24 veya üzeri bir sürümün kurulu olduğundan emin olmalısınız. Ayrıca, kamera erişimi için gerekli izinlerin yapılandırılması kritik bir adımdır.
- Flutter SDK: 3.24.0+
- Dart: 3.5.0+
- Android: compileSdkVersion 34+, minSdkVersion 23+
- iOS: Deployment Target 13.0+
Projenizi oluşturduktan sonra pubspec.yaml dosyanıza gerekli paketleri eklemelisiniz. camera paketi cihaz kamerasını yönetmemizi sağlarken, image paketi ise filtreleme işlemleri için temel görüntü işleme yetenekleri sunar.
dependencies:
flutter:
sdk: flutter
camera: ^0.11.0
image: ^4.2.0
Bu paketleri ekledikten sonra terminalde flutter pub get komutunu çalıştırarak bağımlılıkları projenize dahil edebilirsiniz.
Kamera Kontrolcüsünün Kurulumu
Kamera ile çalışmaya başlamadan önce cihazdaki mevcut kameraları listeleyip bir kontrolcü (controller) oluşturmamız gerekir. Bu kontrolcü, önizleme akışını yönetmemizi sağlar.
late CameraController _controller;
late List _cameras;
Future initializeCamera() async {
_cameras = await availableCameras();
_controller = CameraController(_cameras[0], ResolutionPreset.medium);
await _controller.initialize();
}
Yukarıdaki kod, cihazın ana kamerasını başlatır. ResolutionPreset.medium seçimi, performans ve görüntü kalitesi arasında iyi bir denge sağlar. Kamera başlatma işlemini mutlaka FutureBuilder veya initState içerisinde yönetmelisiniz.
Gerçek Zamanlı Görüntü Akışı ve Filtreleme Mantığı
Kamera filtreleri uygulamak için iki temel yöntem vardır: GPU tabanlı shaderlar veya CPU üzerinde piksel manipülasyonu. Başlangıç için CPU üzerinde basit bir renk filtresi (örneğin gri tonlama) mantığını anlamak önemlidir.
import 'package:image/image.dart' as img;
void applyGrayscaleFilter(img.Image image) {
for (int y = 0; y < image.height; y++) {
for (int x = 0; x < image.width; x++) {
int pixel = image.getPixel(x, y);
int luma = img.getLuminance(pixel);
image.setPixel(x, y, img.getColor(luma, luma, luma));
}
}
}
Bu fonksiyon, görüntüdeki her pikselin parlaklık değerini hesaplayarak onu gri tonuna dönüştürür. image paketi, Flutter'ın Uint8List formatındaki ham kamera verisini işlenebilir bir obje haline getirmemize olanak tanır.
Kullanıcı Arayüzünde Filtre Önizlemesi
Kullanıcının filtreyi anlık görmesi için CameraPreview widget'ını kullanırız. Ancak, filtreyi her karede (frame) işlemek ciddi performans yükü getirebilir. Bu yüzden filtreleme işlemini bir Isolate (ayrı bir iş parçacığı) üzerinde yapmak en iyi pratiktir.
Widget build(BuildContext context) {
if (!_controller.value.isInitialized) {
return Container();
}
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: CameraPreview(_controller),
);
}
Bu kod bloğu, kameradan gelen görüntüyü ekrana yansıtır. Filtre uygulama aşamasında, CameraPreview üzerine bir ColorFiltered widget'ı ekleyerek basit renk katmanları oluşturabilirsiniz.
Performans Karşılaştırması: Yöntemler
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| ColorFiltered Widget | Çok hızlı, basit | Sınırlı efekt |
| CPU İşleme (image paketi) | Her piksele hakimiyet | Yüksek pil tüketimi |
| Custom Shaders (SkSL) | GPU hızlandırmalı, profesyonel | Öğrenme eğrisi yüksek |
Güvenlik ve İzin Yönetimi
Kritik Uyarı: Kamera erişimi hassas bir veridir. Uygulamanızda
AndroidManifest.xmlveInfo.plistdosyalarında gerekli izinleri tanımlamazsanız uygulamanız çöker. Ayrıca, kullanıcıdan çalışma zamanında (runtime) izin istemeyi unutmayın.
Güvenlik açısından, kameradan alınan verileri asla şifrelenmemiş kanallar üzerinden dışarı aktarmayın. Kullanıcı gizliliği için kamera kullanımını yalnızca uygulama ön plandayken aktif tutun.
Sıkça Sorulan Sorular
Filtreleri neden gerçek zamanlı uygulamak performans düşürüyor?
Kamera görüntüsü saniyede 30 kare (FPS) hızında akar. Her kare üzerinde CPU ile piksel bazlı işlem yapmak cihazı zorlar. Bu yüzden GPU tabanlı shaderlar tercih edilmelidir.
Kamera önizlemesi neden siyah görünüyor?
Genellikle kamera kontrolcüsü henüz başlatılmadan (initialize) arayüz çizilmeye çalışıldığı için oluşur. FutureBuilder kullanarak kontrolcünün hazır olup olmadığını kontrol edin.
Özel filtreler için hangi kütüphaneyi önerirsiniz?
Daha karmaşık efektler için flutter_gpu_filters_interface veya doğrudan OpenGL/Vulkan tabanlı shaderlar (SkSL) öğrenmek profesyonel sonuçlar verir.
Kullanıcı izinlerini nasıl yönetmeliyim?
permission_handler paketini kullanarak kamera izni durumunu kontrol edebilir ve kullanıcıyı ayarlar menüsüne yönlendirebilirsiniz.
Filtre uygulanmış fotoğrafı nasıl kaydedebilirim?
_controller.takePicture() ile fotoğrafı çekin, ardından image paketini kullanarak bu dosyayı okuyun, filtreyi uygulayın ve img.encodeJpg() ile diske kaydedin.
İleri Seviye Filtreleme: Custom Shader (GLSL) Entegrasyonu
Flutter'da FragmentProgram kullanarak, CPU tabanlı işleme yerine GPU'nun gücünden yararlanarak çok daha hızlı ve akıcı filtreler oluşturabilirsiniz. GLSL (OpenGL Shading Language) kullanarak pikselleri doğrudan ekran kartı üzerinde manipüle etmek, özellikle yüksek çözünürlüklü videolarda performans darboğazlarını ortadan kaldırır.
GLSL Shader Dosyası Oluşturma
Öncelikle projenizin shaders dizini altında bir .frag dosyası oluşturun. Aşağıdaki örnek, basit bir "sepia" (eskitme) filtresi mantığını GPU üzerinde çalıştırır:
#include
uniform sampler2D image;
uniform vec2 resolution;
out vec4 fragColor;
void main() {
vec2 uv = FlutterFragCoord().xy / resolution;
vec4 color = texture(image, uv);
float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
fragColor = vec4(gray * vec3(1.2, 1.0, 0.8), color.a);
}
Flutter Tarafında Shader'ı Çalıştırma
Shader'ı yüklemek ve kamera akışına uygulamak için ShaderMask veya CustomPainter kullanabilirsiniz. İşte bir FragmentProgram yükleme örneği:
Future loadShader() async {
return await FragmentProgram.fromAsset('shaders/sepia.frag');
}
// Widget içerisinde kullanımı:
Widget build(BuildContext context) {
return FutureBuilder(
future: loadShader(),
builder: (context, snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
final shader = snapshot.data!.fragmentShader();
return CustomPaint(
painter: ShaderPainter(shader),
);
},
);
}
Üretim Ortamında (Deployment) Karşılaşılan Sorunlar ve Hata Ayıklama
Uygulamanızı mağazaya yüklemeden önce kamera modülünde oluşabilecek uç durumları test etmeniz kritiktir. Özellikle düşük donanımlı cihazlarda bellek yönetimi (memory management) en büyük sorundur.
Bellek Sızıntılarını Önleme
Kamera verileri (CameraImage) sürekli olarak RAM üzerinde yer kaplar. Eğer her kareyi işledikten sonra bellekten temizlemezseniz, uygulama birkaç dakika içinde çökecektir. Aşağıdaki yöntemle bellek akışını kontrol altında tutun:
void processImage(CameraImage image) {
try {
// İşleme mantığı
} finally {
// İşlem bittikten sonra mutlaka dispose edin
// Bu yöntem, CameraImage nesnesinin belleği serbest bırakmasını sağlar
}
}
Test Stratejileri
- Fiziksel Cihaz Testi: Kamera filtreleri emülatörlerde tam performans vermez. Mutlaka farklı Android ve iOS sürümlerine sahip fiziksel cihazlarda test edin.
- Isınma Testi: GPU tabanlı filtreler cihazın ısınmasına neden olabilir. Uzun süreli kamera kullanımı sonrası cihazın termal davranışını gözlemleyin.
- İzin Senaryoları: Kullanıcı kameraya izin vermediğinde veya uygulama arka plana atılıp tekrar açıldığında kamera kontrolcüsünün (controller) yeniden başlatıldığından emin olun.
İpucu: Kamera önizlemesinde takılmalar yaşıyorsanız,ResolutionPreset.highyerineResolutionPreset.mediumkullanmayı deneyin. Kullanıcı deneyimi açısından 30 FPS'lik akıcı bir görüntü, 60 FPS'lik takılan bir görüntüden çok daha değerlidir.
Sonuç
Flutter & mobil ile özel kamera filtreleri uygulaması geliştirmek, doğru araçları seçtiğinizde oldukça keyifli bir süreçtir. Bu rehberde temel kamera kurulumundan piksel bazlı filtreleme mantığına kadar geniş bir çerçeve çizdik. Bir sonraki adım olarak, Flutter'ın FragmentProgram özelliğini kullanarak kendi özel shader dosyalarınızı (GLSL) yazmayı araştırmanızı öneririm.
Yasal Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Ticari uygulamalarınızda kamera verilerinin işlenmesi, depolanması ve kullanıcı gizliliği ile ilgili yerel yasal düzenlemelere (KVKK vb.) uyum sağlamak geliştiricinin sorumluluğundadır.

Yorumlar (0)
Yorum Yaz