image_marker_viewer 1.0.0 copy "image_marker_viewer: ^1.0.0" to clipboard
image_marker_viewer: ^1.0.0 copied to clipboard

A Flutter package for adding interactive markers on images with custom colors, titles, and notes. Supports web, mobile, and desktop platforms.

example/lib/main.dart

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:file_picker/file_picker.dart';
import 'package:image_marker_viewer/widgets/image_marker_viewer.dart';
import 'package:image_marker_viewer/controllers/image_marker_controller.dart';
import 'package:image_marker_viewer/models/image_marker.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Image Marker Viewer Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MarkerExample(),
    );
  }
}

class MarkerExample extends StatefulWidget {
  const MarkerExample({super.key});

  @override
  State<MarkerExample> createState() => _MarkerExampleState();
}

class _MarkerExampleState extends State<MarkerExample> {
  final controller = Get.put(ImageMarkerController());
  Uint8List? selectedImageBytes;
  ImageMarker? selectedMarker;
  final List<ImageMarker> allMarkers = [];

  Future<void> pickImage() async {
    final result = await FilePicker.platform.pickFiles(
      type: FileType.image,
    );
    if (result != null && result.files.single.bytes != null) {
      setState(() {
        selectedImageBytes = result.files.single.bytes;
        allMarkers.clear();
        selectedMarker = null;
      });
    }
  }

  void _onMarkerAdded(ImageMarker marker) {
    setState(() {
      allMarkers.add(marker);
    });
  }

  void _onMarkerSelected(ImageMarker marker) {
    setState(() {
      selectedMarker = marker;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Image Marker Viewer'),
        actions: [
          IconButton(
            icon: const Icon(Icons.download),
            onPressed: () {
              final json = controller.exportToJson();
              ScaffoldMessenger.of(context).showSnackBar(
                SnackBar(content: Text('JSON export:\n$json')),
              );
            },
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: pickImage,
        child: const Icon(Icons.add_photo_alternate),
      ),
      body: selectedImageBytes == null
          ? const Center(child: Text('Henüz bir görsel seçilmedi.'))
          : Row(
              children: [
                // Sol taraf - Görsel
                Expanded(
                  flex: 2,
                  child: SizedBox(
                    height: MediaQuery.of(context).size.height ,
                    width: MediaQuery.of(context).size.width ,
                
                 
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(12),
                      child: ImageMarkerViewer(
                        image: MemoryImage(selectedImageBytes!),
                        onMarkerAdded: _onMarkerAdded,
                        onMarkerSelected: _onMarkerSelected,
                      ),
                    ),
                  ),
                ),
                // Sağ taraf - Marker Bilgileri
                Expanded(
                  flex: 1,
                  child: Container(
                    margin: const EdgeInsets.all(16),
                    padding: const EdgeInsets.all(20),
                    decoration: BoxDecoration(
                      color: Colors.grey[50],
                      borderRadius: BorderRadius.circular(12),
                      border: Border.all(color: Colors.grey[300]!),
                    ),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          children: [
                            Icon(Icons.info_outline, color: Colors.grey[700]),
                            const SizedBox(width: 8),
                            Text(
                              'Marker Bilgileri',
                              style: Theme.of(context)
                                  .textTheme
                                  .titleLarge
                                  ?.copyWith(
                                    fontWeight: FontWeight.bold,
                                  ),
                            ),
                          ],
                        ),
                        const SizedBox(height: 20),
                        // Seçili Marker Bilgisi
                        if (selectedMarker != null)
                          Expanded(
                            child: SingleChildScrollView(
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Container(
                                    padding: const EdgeInsets.all(16),
                                    decoration: BoxDecoration(
                                      color: selectedMarker!.color
                                          .withOpacity(0.1),
                                      borderRadius: BorderRadius.circular(8),
                                      border: Border.all(
                                        color: selectedMarker!.color,
                                        width: 2,
                                      ),
                                    ),
                                    child: Column(
                                      crossAxisAlignment:
                                          CrossAxisAlignment.start,
                                      children: [
                                        Row(
                                          children: [
                                            Container(
                                              width: 24,
                                              height: 24,
                                              decoration: BoxDecoration(
                                                color: selectedMarker!.color,
                                                shape: BoxShape.circle,
                                                border: Border.all(
                                                  color: Colors.white,
                                                  width: 2,
                                                ),
                                              ),
                                            ),
                                            const SizedBox(width: 12),
                                            Expanded(
                                              child: Text(
                                                selectedMarker!.markerTitle ??
                                                    'Başlıksız Marker',
                                                style: Theme.of(context)
                                                    .textTheme
                                                    .titleMedium
                                                    ?.copyWith(
                                                      fontWeight:
                                                          FontWeight.bold,
                                                    ),
                                              ),
                                            ),
                                          ],
                                        ),
                                        if (selectedMarker!.markerTitle !=
                                                null &&
                                            selectedMarker!
                                                .markerTitle!.isNotEmpty) ...[
                                          const SizedBox(height: 12),
                                          Row(
                                            crossAxisAlignment:
                                                CrossAxisAlignment.start,
                                            children: [
                                              Icon(
                                                Icons.title,
                                                size: 18,
                                                color: Colors.grey[600],
                                              ),
                                              const SizedBox(width: 8),
                                              Expanded(
                                                child: Text(
                                                  selectedMarker!.markerTitle!,
                                                  style: TextStyle(
                                                    fontSize: 14,
                                                    color: Colors.grey[800],
                                                  ),
                                                ),
                                              ),
                                            ],
                                          ),
                                        ],
                                        if (selectedMarker!.note != null &&
                                            selectedMarker!
                                                .note!.isNotEmpty) ...[
                                          const SizedBox(height: 12),
                                          Row(
                                            crossAxisAlignment:
                                                CrossAxisAlignment.start,
                                            children: [
                                              Icon(
                                                Icons.note,
                                                size: 18,
                                                color: Colors.grey[600],
                                              ),
                                              const SizedBox(width: 8),
                                              Expanded(
                                                child: Text(
                                                  selectedMarker!.note!,
                                                  style: TextStyle(
                                                    fontSize: 14,
                                                    color: Colors.grey[800],
                                                  ),
                                                ),
                                              ),
                                            ],
                                          ),
                                        ],
                                        const SizedBox(height: 12),
                                        Row(
                                          children: [
                                            Icon(
                                              Icons.palette,
                                              size: 18,
                                              color: Colors.grey[600],
                                            ),
                                            const SizedBox(width: 8),
                                            Text(
                                              'Renk: ',
                                              style: TextStyle(
                                                fontSize: 14,
                                                color: Colors.grey[600],
                                              ),
                                            ),
                                            Container(
                                              width: 20,
                                              height: 20,
                                              decoration: BoxDecoration(
                                                color: selectedMarker!.color,
                                                shape: BoxShape.circle,
                                                border: Border.all(
                                                  color: Colors.grey[300]!,
                                                ),
                                              ),
                                            ),
                                            const SizedBox(width: 8),
                                            Text(
                                              '#${selectedMarker!.color.value.toRadixString(16).substring(2).toUpperCase()}',
                                              style: TextStyle(
                                                fontSize: 12,
                                                color: Colors.grey[600],
                                                fontFamily: 'monospace',
                                              ),
                                            ),
                                          ],
                                        ),
                                        const SizedBox(height: 12),
                                        Row(
                                          children: [
                                            Icon(
                                              Icons.location_on,
                                              size: 18,
                                              color: Colors.grey[600],
                                            ),
                                            const SizedBox(width: 8),
                                            Text(
                                              'Pozisyon: ',
                                              style: TextStyle(
                                                fontSize: 14,
                                                color: Colors.grey[600],
                                              ),
                                            ),
                                            Text(
                                              '(${selectedMarker!.x.toStringAsFixed(2)}, ${selectedMarker!.y.toStringAsFixed(2)})',
                                              style: TextStyle(
                                                fontSize: 12,
                                                color: Colors.grey[800],
                                                fontFamily: 'monospace',
                                              ),
                                            ),
                                          ],
                                        ),
                                      ],
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          )
                        else
                          Expanded(
                            child: Center(
                              child: Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: [
                                  Icon(
                                    Icons.touch_app,
                                    size: 64,
                                    color: Colors.grey[400],
                                  ),
                                  const SizedBox(height: 16),
                                  Text(
                                    'Marker\'a tıklayın',
                                    style: TextStyle(
                                      fontSize: 16,
                                      color: Colors.grey[600],
                                    ),
                                  ),
                                  const SizedBox(height: 8),
                                  Text(
                                    'Bilgileri burada görüntüleyin',
                                    style: TextStyle(
                                      fontSize: 14,
                                      color: Colors.grey[500],
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        const Divider(),
                        // Tüm Markerlar Listesi
                        Text(
                          'Tüm Markerlar (${allMarkers.length})',
                          style:
                              Theme.of(context).textTheme.titleSmall?.copyWith(
                                    fontWeight: FontWeight.bold,
                                  ),
                        ),
                        const SizedBox(height: 12),
                        if (allMarkers.isEmpty)
                          Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Text(
                              'Henüz marker eklenmedi',
                              style: TextStyle(
                                color: Colors.grey[600],
                                fontSize: 12,
                              ),
                            ),
                          )
                        else
                          SizedBox(
                            height: 100,
                            child: ListView.builder(
                              scrollDirection: Axis.horizontal,
                              itemCount: allMarkers.length,
                              itemBuilder: (context, index) {
                                final marker = allMarkers[index];
                                return GestureDetector(
                                  onTap: () {
                                    setState(() {
                                      selectedMarker = marker;
                                    });
                                  },
                                  child: Container(
                                    width: 80,
                                    margin: const EdgeInsets.only(right: 8),
                                    padding: const EdgeInsets.all(12),
                                    decoration: BoxDecoration(
                                      color: marker == selectedMarker
                                          ? marker.color.withOpacity(0.2)
                                          : Colors.white,
                                      borderRadius: BorderRadius.circular(8),
                                      border: Border.all(
                                        color: marker == selectedMarker
                                            ? marker.color
                                            : Colors.grey[300]!,
                                        width: marker == selectedMarker ? 2 : 1,
                                      ),
                                    ),
                                    child: Column(
                                      mainAxisAlignment:
                                          MainAxisAlignment.center,
                                      children: [
                                        Container(
                                          width: 24,
                                          height: 24,
                                          decoration: BoxDecoration(
                                            color: marker.color,
                                            shape: BoxShape.circle,
                                            border: Border.all(
                                              color: Colors.white,
                                              width: 2,
                                            ),
                                          ),
                                        ),
                                        const SizedBox(height: 8),
                                        Text(
                                          marker.markerTitle ??
                                              'Marker ${index + 1}',
                                          style: TextStyle(
                                            fontSize: 10,
                                            fontWeight: FontWeight.bold,
                                            color: Colors.grey[800],
                                          ),
                                          maxLines: 1,
                                          overflow: TextOverflow.ellipsis,
                                        ),
                                      ],
                                    ),
                                  ),
                                );
                              },
                            ),
                          ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
    );
  }
}
5
likes
0
points
179
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter package for adding interactive markers on images with custom colors, titles, and notes. Supports web, mobile, and desktop platforms.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_colorpicker, get

More

Packages that depend on image_marker_viewer