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

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

image_marker_viewer #

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

Features #

  • πŸ“ Interactive Markers: Add markers by tapping on images
  • 🎨 Custom Colors: Choose from predefined colors or use RGB color picker
  • πŸ“ Title & Notes: Add titles and notes to each marker
  • πŸ–±οΈ Easy Management: Tap to edit, long press to delete markers
  • πŸ’Ύ Export/Import: Export markers to JSON and import them back
  • πŸ“± Cross-Platform: Works on web, iOS, Android, macOS, Linux, and Windows
  • 🎯 Responsive: Markers stay in their relative position when image is resized
  • ⚑ Optimized Performance: Each marker manages its own state, reducing unnecessary rebuilds
  • πŸ—οΈ Modular Architecture: Clean, maintainable code following SOLID principles
  • πŸ“Έ Photo Support: Attach up to 3 photos per marker (Base64 encoded)

Getting Started #

Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  image_marker_viewer: ^1.0.2
  get: ^4.7.2

Usage #

Basic Example

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:image_marker_viewer/image_marker_viewer.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      home: Scaffold(
        body: ImageMarkerViewer(
          image: NetworkImage('https://example.com/image.jpg'),
          onMarkerAdded: (marker) {
            print('Marker added: ${marker.markerTitle}');
          },
          onMarkerSelected: (marker) {
            print('Marker selected: ${marker.markerTitle}');
          },
        ),
      ),
    );
  }
}

With File Picker

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/image_marker_viewer.dart';

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  Uint8List? selectedImageBytes;

  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;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: selectedImageBytes == null
          ? Center(child: Text('No image selected'))
          : ImageMarkerViewer(
              image: MemoryImage(selectedImageBytes!),
              onMarkerAdded: (marker) {
                print('Marker added at (${marker.x}, ${marker.y})');
              },
            ),
      floatingActionButton: FloatingActionButton(
        onPressed: pickImage,
        child: Icon(Icons.add_photo_alternate),
      ),
    );
  }
}

Multiple Images with Separate Marker Lists

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:image_marker_viewer/image_marker_viewer.dart';

// Each image can have its own marker list using tags
ImageMarkerViewer(
  image: MemoryImage(image1Bytes),
  tag: 'image_1', // Unique tag for this image
)

ImageMarkerViewer(
  image: MemoryImage(image2Bytes),
  tag: 'image_2', // Different tag for different markers
)

// Or use external controller
final controller = ImageMarkerController();
ImageMarkerViewer(
  image: MemoryImage(imageBytes),
  controller: controller,
)

Export/Import Markers

import 'package:image_marker_viewer/image_marker_viewer.dart';
import 'package:get/get.dart';

// Get the controller (with tag if used)
final controller = Get.find<ImageMarkerController>(tag: 'image_1');

// Export markers to JSON
String json = controller.exportToJson();
print(json);

// Import markers from JSON
controller.importFromJson(json);

API Reference #

ImageMarkerViewer #

The main widget for displaying images with markers.

Properties

  • image (ImageProvider, required): The image to display
  • enableAddMarker (bool, default: true): Enable/disable adding new markers
  • onMarkerAdded (Function(ImageMarker)?): Callback when a marker is added
  • onMarkerSelected (Function(ImageMarker)?): Callback when a marker is selected
  • tag (String?, optional): Unique tag for this image's controller. Each image with a different tag will have its own marker list
  • controller (ImageMarkerController?, optional): External controller instance. If provided, tag is ignored

ImageMarkerController #

Controller for managing markers.

Methods

  • addMarker(ImageMarker marker): Add a new marker
  • removeMarker(int index): Remove a marker at the given index
  • updateTitle(int index, String? title): Update marker title
  • updateNote(int index, String? note): Update marker note
  • updateColor(int index, Color color): Update marker color
  • updatePosition(int index, double x, double y): Update marker position (x, y in 0.0-1.0 range)
  • addPhoto(int index, String photoBase64): Add a photo to a marker (max 3 photos per marker)
  • removePhoto(int index, int photoIndex): Remove a photo from a marker
  • exportToJson(): Export all markers to JSON string
  • importFromJson(String jsonData): Import markers from JSON string

ImageMarker #

Model for marker data.

Properties

  • x (double): X coordinate (0.0 to 1.0)
  • y (double): Y coordinate (0.0 to 1.0)
  • color (Color): Marker color
  • markerTitle (String?): Optional marker title
  • note (String?): Optional marker note
  • photos (List

Interaction #

  • Tap on image: Add a new marker (if enableAddMarker is true)
  • Tap on marker: Edit the marker
  • Long press on marker: Delete the marker (with confirmation)
  • Drag marker: Move marker to a new position by dragging it

What's New in v1.0.2 #

Performance Improvements #

  • Optimized State Management: Each marker widget now manages its own state independently using reactive programming. This means when one marker changes, only that specific marker rebuilds, not the entire UI.
  • Reduced Rebuilds: Significant performance improvement when working with multiple markers.

Code Quality #

  • SOLID Principles: Complete refactoring following SOLID design principles for better maintainability
  • Modular Architecture: Code split into logical, reusable components
  • Comprehensive Documentation: Added DartDoc comments throughout the codebase
  • Enhanced Error Handling: Improved bounds checking and error handling

Bug Fixes #

  • Fixed marker dragging/positioning issues for stable marker movement
  • Improved marker position calculation accuracy

Example #

See the example directory for a complete example application.

License #

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

Issues #

If you encounter any issues, please file an issue on the GitHub repository.

5
likes
140
points
175
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

Documentation

API reference

License

MIT (license)

Dependencies

file_picker, flutter, flutter_colorpicker, get, image_picker

More

Packages that depend on image_marker_viewer