Untitled
unknown
plain_text
a year ago
21 kB
10
Indexable
import 'dart:typed_data';
import 'dart:io' as io;
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as img;
import 'package:file_picker/file_picker.dart';
// dart:html sadece web için import edilir
import 'dart:html' as html
if (dart.library.io) 'unsupported_platform.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ImageSquareDrawer(),
);
}
}
class ImageSquareDrawer extends StatefulWidget {
@override
_ImageSquareDrawerState createState() => _ImageSquareDrawerState();
}
class _ImageSquareDrawerState extends State<ImageSquareDrawer> {
Uint8List? _selectedImageData;
Uint8List? _edgeDetectedImageData;
Rect? _highlightedRect;
TextEditingController _coordinatesController = TextEditingController();
Color? _color1;
String _color1Hex = "";
String _color1RGB = "";
Future<void> _pickImageWeb() async {
if (kIsWeb) {
// Web için
final uploadInput = html.FileUploadInputElement();
uploadInput.accept = 'image/*';
uploadInput.click();
uploadInput.onChange.listen((e) {
final files = uploadInput.files;
if (files!.isEmpty) return;
final reader = html.FileReader();
reader.readAsArrayBuffer(files[0]);
reader.onLoadEnd.listen((e) {
setState(() {
_selectedImageData = reader.result as Uint8List?;
_highlightedRect = null;
_edgeDetectedImageData = null;
});
});
});
} else {
// Mobil platformlar için
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.image,
);
if (result != null) {
setState(() {
_selectedImageData = result.files.first.bytes;
_highlightedRect = null;
_edgeDetectedImageData = null;
});
}
}
}
void _setCoordinates(String coordinates) {
_coordinatesController.text = coordinates;
_drawSquare(coordinates);
}
void _drawSquare(String coordinates) {
if (_selectedImageData == null) return;
List<String> parts = coordinates.split(' ');
double centerX = double.parse(parts[1]);
double centerY = double.parse(parts[2]);
double width = double.parse(parts[3]);
double height = double.parse(parts[4]);
double startX = centerX - width / 2;
double startY = centerY - height / 2;
setState(() {
_highlightedRect = Rect.fromLTWH(startX, startY, width, height);
_edgeDetectedImageData = null;
});
}
img.Image _applyThreshold(img.Image image, int threshold) {
img.Image grayImage = img.grayscale(image);
img.Image thresholdedImage = img.Image.from(grayImage);
for (int y = 0; y < thresholdedImage.height; y++) {
for (int x = 0; x < thresholdedImage.width; x++) {
int pixel = thresholdedImage.getPixel(x, y);
int brightness = img.getLuminance(pixel);
if (brightness < threshold) {
thresholdedImage.setPixel(x, y, img.getColor(0, 0, 0));
} else {
thresholdedImage.setPixel(x, y, img.getColor(255, 255, 255));
}
}
}
return thresholdedImage;
}
void _applyEdgeDetection() {
if (_selectedImageData == null) return;
img.Image image = img.decodeImage(_selectedImageData!)!;
List<String> coordinateSets = _coordinatesController.text.trim().split('\n');
for (String coordinateSet in coordinateSets) {
List<String> parts = coordinateSet.split(' ');
int pieceNumber = int.parse(parts[0]);
double centerX = double.parse(parts[1]);
double centerY = double.parse(parts[2]);
double width = double.parse(parts[3]);
double height = double.parse(parts[4]);
double startX = centerX - width / 2;
double startY = centerY - height / 2;
int rectX = (startX * image.width).toInt();
int rectY = (startY * image.height).toInt();
int rectWidth = (width * image.width).toInt();
int rectHeight = (height * image.height).toInt();
rectX = (rectX + rectWidth * 0.05).toInt();
rectY = (rectY + rectHeight * 0.05).toInt();
rectWidth = (rectWidth * 0.9).toInt();
rectHeight = (rectHeight * 0.9).toInt();
img.Image croppedImage = img.copyCrop(image, rectX, rectY, rectWidth, rectHeight);
img.Image thresholdedImage = _applyThreshold(croppedImage, 128);
img.Image edgeDetectedImage = img.sobel(thresholdedImage);
List<Offset> contour = _findLargestContour(edgeDetectedImage);
if (contour.isNotEmpty) {
_drawContour(image, contour, rectX, rectY);
Color averageColor = _calculateAverageColorInsideContour(image, contour, rectX, rectY);
_drawColorOnPiece(image, pieceNumber, averageColor, rectX, rectY, rectWidth, rectHeight);
}
}
_edgeDetectedImageData = Uint8List.fromList(img.encodePng(image));
setState(() {});
}
List<Offset> _findLargestContour(img.Image edgeDetectedImage) {
int maxArea = 0;
List<Offset>? largestContour;
for (int y = 0; y < edgeDetectedImage.height; y++) {
for (int x = 0; x < edgeDetectedImage.width; x++) {
int pixel = edgeDetectedImage.getPixel(x, y);
if (img.getLuminance(pixel) > 0) {
List<Offset> contour = _traceContour(edgeDetectedImage, x, y);
if (contour.isNotEmpty) {
int area = contour.length;
if (area > 100) {
if (area > maxArea) {
maxArea = area;
largestContour = contour;
}
}
}
}
}
}
return largestContour ?? [];
}
List<Offset> _traceContour(img.Image image, int startX, int startY) {
int x = startX;
int y = startY;
int dir = 0;
List<Offset> contour = [];
do {
if (x >= 0 && x < image.width && y >= 0 && y < image.height) {
contour.add(Offset(x.toDouble(), y.toDouble()));
if (img.getLuminance(image.getPixel(x, y)) > 0) {
image.setPixel(x, y, img.getColor(255, 0, 0, 255));
dir = (dir + 3) % 4;
} else {
dir = (dir + 1) % 4;
}
} else {
break;
}
switch (dir) {
case 0: x += 1; break;
case 1: y += 1; break;
case 2: x -= 1; break;
case 3: y -= 1; break;
}
} while ((x != startX || y != startY) && contour.length < 10000);
return contour;
}
void _drawContour(img.Image image, List<Offset> contour, int offsetX, int offsetY) {
int transparentColor = img.getColor(0, 0, 0, 0);
for (int i = 0; i < contour.length - 1; i++) {
_drawLine(
image,
Offset(contour[i].dx + offsetX, contour[i].dy + offsetY),
Offset(contour[i + 1].dx + offsetX, contour[i + 1].dy + offsetY),
transparentColor,
);
}
_drawLine(
image,
Offset(contour.last.dx + offsetX, contour.last.dy + offsetY),
Offset(contour.first.dx + offsetX, contour.first.dy + offsetY),
transparentColor,
);
}
void _drawLine(img.Image image, Offset p1, Offset p2, int color) {
int x0 = p1.dx.toInt();
int y0 = p1.dy.toInt();
int x1 = p2.dx.toInt();
int y1 = p2.dy.toInt();
int dx = (x1 - x0).abs();
int dy = (y1 - y0).abs();
int sx = x0 < x1 ? 1 : -1;
int sy = y0 < y1 ? 1 : -1;
int err = dx - dy;
import 'dart:typed_data';
import 'dart:io' as io;
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as img;
import 'package:file_picker/file_picker.dart';
// dart:html sadece web için import edilir
import 'dart:html' as html
if (dart.library.io) 'unsupported_platform.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ImageSquareDrawer(),
);
}
}
class ImageSquareDrawer extends StatefulWidget {
@override
_ImageSquareDrawerState createState() => _ImageSquareDrawerState();
}
class _ImageSquareDrawerState extends State<ImageSquareDrawer> {
Uint8List? _selectedImageData;
Uint8List? _edgeDetectedImageData;
Rect? _highlightedRect;
TextEditingController _coordinatesController = TextEditingController();
Color? _color1;
String _color1Hex = "";
String _color1RGB = "";
Future<void> _pickImageWeb() async {
if (kIsWeb) {
// Web için
final uploadInput = html.FileUploadInputElement();
uploadInput.accept = 'image/*';
uploadInput.click();
uploadInput.onChange.listen((e) {
final files = uploadInput.files;
if (files!.isEmpty) return;
final reader = html.FileReader();
reader.readAsArrayBuffer(files[0]);
reader.onLoadEnd.listen((e) {
setState(() {
_selectedImageData = reader.result as Uint8List?;
_highlightedRect = null;
_edgeDetectedImageData = null;
});
});
});
} else {
// Mobil platformlar için
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.image,
);
if (result != null) {
setState(() {
_selectedImageData = result.files.first.bytes;
_highlightedRect = null;
_edgeDetectedImageData = null;
});
}
}
}
void _setCoordinates(String coordinates) {
_coordinatesController.text = coordinates;
_drawSquare(coordinates);
}
void _drawSquare(String coordinates) {
if (_selectedImageData == null) return;
List<String> parts = coordinates.split(' ');
double centerX = double.parse(parts[1]);
double centerY = double.parse(parts[2]);
double width = double.parse(parts[3]);
double height = double.parse(parts[4]);
double startX = centerX - width / 2;
double startY = centerY - height / 2;
setState(() {
_highlightedRect = Rect.fromLTWH(startX, startY, width, height);
_edgeDetectedImageData = null;
});
}
img.Image _applyThreshold(img.Image image, int threshold) {
img.Image grayImage = img.grayscale(image);
img.Image thresholdedImage = img.Image.from(grayImage);
for (int y = 0; y < thresholdedImage.height; y++) {
for (int x = 0; x < thresholdedImage.width; x++) {
int pixel = thresholdedImage.getPixel(x, y);
int brightness = img.getLuminance(pixel);
if (brightness < threshold) {
thresholdedImage.setPixel(x, y, img.getColor(0, 0, 0));
} else {
thresholdedImage.setPixel(x, y, img.getColor(255, 255, 255));
}
}
}
return thresholdedImage;
}
void _applyEdgeDetection() {
if (_selectedImageData == null) return;
img.Image image = img.decodeImage(_selectedImageData!)!;
List<String> coordinateSets = _coordinatesController.text.trim().split('\n');
for (String coordinateSet in coordinateSets) {
List<String> parts = coordinateSet.split(' ');
int pieceNumber = int.parse(parts[0]);
double centerX = double.parse(parts[1]);
double centerY = double.parse(parts[2]);
double width = double.parse(parts[3]);
double height = double.parse(parts[4]);
double startX = centerX - width / 2;
double startY = centerY - height / 2;
int rectX = (startX * image.width).toInt();
int rectY = (startY * image.height).toInt();
int rectWidth = (width * image.width).toInt();
int rectHeight = (height * image.height).toInt();
rectX = (rectX + rectWidth * 0.05).toInt();
rectY = (rectY + rectHeight * 0.05).toInt();
rectWidth = (rectWidth * 0.9).toInt();
rectHeight = (rectHeight * 0.9).toInt();
img.Image croppedImage = img.copyCrop(image, rectX, rectY, rectWidth, rectHeight);
img.Image thresholdedImage = _applyThreshold(croppedImage, 128);
img.Image edgeDetectedImage = img.sobel(thresholdedImage);
List<Offset> contour = _findLargestContour(edgeDetectedImage);
if (contour.isNotEmpty) {
_drawContour(image, contour, rectX, rectY);
Color averageColor = _calculateAverageColorInsideContour(image, contour, rectX, rectY);
_drawColorOnPiece(image, pieceNumber, averageColor, rectX, rectY, rectWidth, rectHeight);
}
}
_edgeDetectedImageData = Uint8List.fromList(img.encodePng(image));
setState(() {});
}
List<Offset> _findLargestContour(img.Image edgeDetectedImage) {
int maxArea = 0;
List<Offset>? largestContour;
for (int y = 0; y < edgeDetectedImage.height; y++) {
for (int x = 0; x < edgeDetectedImage.width; x++) {
int pixel = edgeDetectedImage.getPixel(x, y);
if (img.getLuminance(pixel) > 0) {
List<Offset> contour = _traceContour(edgeDetectedImage, x, y);
if (contour.isNotEmpty) {
int area = contour.length;
if (area > 100) {
if (area > maxArea) {
maxArea = area;
largestContour = contour;
}
}
}
}
}
}
return largestContour ?? [];
}
List<Offset> _traceContour(img.Image image, int startX, int startY) {
int x = startX;
int y = startY;
int dir = 0;
List<Offset> contour = [];
do {
if (x >= 0 && x < image.width && y >= 0 && y < image.height) {
contour.add(Offset(x.toDouble(), y.toDouble()));
if (img.getLuminance(image.getPixel(x, y)) > 0) {
image.setPixel(x, y, img.getColor(255, 0, 0, 255));
dir = (dir + 3) % 4;
} else {
dir = (dir + 1) % 4;
}
} else {
break;
}
switch (dir) {
case 0: x += 1; break;
case 1: y += 1; break;
case 2: x -= 1; break;
case 3: y -= 1; break;
}
} while ((x != startX || y != startY) && contour.length < 10000);
return contour;
}
void _drawContour(img.Image image, List<Offset> contour, int offsetX, int offsetY) {
int transparentColor = img.getColor(0, 0, 0, 0);
for (int i = 0; i < contour.length - 1; i++) {
_drawLine(
image,
Offset(contour[i].dx + offsetX, contour[i].dy + offsetY),
Offset(contour[i + 1].dx + offsetX, contour[i + 1].dy + offsetY),
transparentColor,
);
}
_drawLine(
image,
Offset(contour.last.dx + offsetX, contour.last.dy + offsetY),
Offset(contour.first.dx + offsetX, contour.first.dy + offsetY),
transparentColor,
);
}
void _drawLine(img.Image image, Offset p1, Offset p2, int color) {
int x0 = p1.dx.toInt();
int y0 = p1.dy.toInt();
int x1 = p2.dx.toInt();
int y1 = p2.dy.toInt();
int dx = (x1 - x0).abs();
int dy = (y1 - y0).abs();
int sx = x0 < x1 ? 1 : -1;
int sy = y0 < y1 ? 1 : -1;
int err = dx - dy;
while (true) {
image.setPixel(x0, y0, color);
if (x0 == x1 && y0 == y1) break;
int e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
x0 += sx;
}
if (e2 < dx) {
err += dx;
y0 += sy;
}
}
}
Color _calculateAverageColorInsideContour(img.Image image, List<Offset> contour, int offsetX, int offsetY) {
int redSum = 0;
int greenSum = 0;
int blueSum = 0;
int pixelCount = 0;
Set<Offset> visitedPoints = {};
Set<Offset> contourPoints = contour.toSet();
double minX = double.infinity;
double minY = double.infinity;
double maxX = double.negativeInfinity;
double maxY = double.negativeInfinity;
for (Offset point in contour) {
minX = min(minX, point.dx);
minY = min(minY, point.dy);
maxX = max(maxX, point.dx);
maxY = max(maxY, point.dy);
}
for (int y = minY.toInt(); y <= maxY.toInt(); y++) {
for (int x = minX.toInt(); x <= maxX.toInt(); x++) {
Offset currentPoint = Offset(x.toDouble(), y.toDouble());
if (_isPointInsideContour(currentPoint, contour) && !visitedPoints.contains(currentPoint)) {
visitedPoints.add(currentPoint);
if (contourPoints.contains(currentPoint)) {
continue;
}
int pixel = image.getPixel(x + offsetX, y + offsetY);
redSum += img.getRed(pixel);
greenSum += img.getGreen(pixel);
blueSum += img.getBlue(pixel);
pixelCount++;
}
}
}
if (pixelCount == 0) return Colors.grey;
int avgRed = (redSum / pixelCount).round();
int avgGreen = (greenSum / pixelCount).round();
int avgBlue = (blueSum / pixelCount).round();
double brightnessFactor = 1.2;
avgRed = (avgRed * brightnessFactor).clamp(0, 255).toInt();
avgGreen = (avgGreen * brightnessFactor).clamp(0, 255).toInt();
avgBlue = (avgBlue * brightnessFactor).clamp(0, 255).toInt();
return Color.fromRGBO(avgRed, avgGreen, avgBlue, 1.0);
}
bool _isPointInsideContour(Offset point, List<Offset> contour) {
int intersectCount = 0;
for (int i = 0; i < contour.length; i++) {
Offset p1 = contour[i];
Offset p2 = contour[(i + 1) % contour.length];
if ((p1.dy > point.dy) != (p2.dy > point.dy)) {
double slope = (point.dy - p1.dy) / (p2.dy - p1.dy);
if (point.dx < p1.dx + slope * (p2.dx - p1.dx)) {
intersectCount++;
}
}
}
return (intersectCount % 2) != 0;
}
void _drawColorOnPiece(img.Image image, int pieceNumber, Color color, int x, int y, int width, int height) {
img.fillRect(image, x + width ~/ 4, y + height ~/ 4, x + width * 3 ~/ 4, y + height * 3 ~/ 4, img.getColor(color.red, color.green, color.blue));
img.drawString(image, img.arial_24, x + width ~/ 2, y + height ~/ 2, '$pieceNumber', color: img.getColor(0, 0, 0));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Image Square Drawer with Edge Detection')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (_selectedImageData == null)
ElevatedButton(
onPressed: _pickImageWeb,
child: Text('Select Image'),
)
else
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Stack(
alignment: Alignment.center,
children: [
Image.memory(
_selectedImageData!,
width: 400,
height: 400,
),
if (_highlightedRect != null)
Positioned(
left: _highlightedRect!.left * 400,
top: _highlightedRect!.top * 400,
child: Container(
width: _highlightedRect!.width * 400,
height: _highlightedRect!.height * 400,
decoration: BoxDecoration(
border: Border.all(color: Colors.red, width: 2),
),
),
),
],
),
if (_edgeDetectedImageData != null)
Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Column(
children: [
Text('Edge Detected Image:'),
Image.memory(
_edgeDetectedImageData!,
width: 400,
height: 400,
),
],
),
),
],
),
TextField(
controller: _coordinatesController,
decoration: InputDecoration(
hintText: 'Coordinates (e.g., 0.5 0.5 0.2 0.2)',
),
maxLines: 5,
),
ElevatedButton(
onPressed: _applyEdgeDetection,
child: Text('Apply Edge Detection'),
),
SizedBox(height: 20),
if (_color1 != null) ...[
Text('Detected Average Color:'),
Container(
width: 50,
height: 50,
color: _color1,
),
SizedBox(height: 5),
Text('Hex: $_color1Hex'),
Text('RGB: $_color1RGB'),
],
],
),
],
),
),
);
}
}Editor is loading...
Leave a Comment