How to remove surrounding whitespace from an Image in Dart Flutter? - image

Users write to screen and create image and send to our platform. Each image is a picture of something(hand written text) which is taken with a white background. I would like to remove all the white parts of the image get the content only user writes. Is it possible using image-processing in flutter? If possible how?

You can do image processing in Dart (Flutter is just a UI Framework, image processing is an algorithm, so not related to UI, but with the language itself).
You can try to use the image package, open the image, decode its bytes and apply any image processing algorithms there.
This library will help you extract the image bytes, but if you need more hardcore image processing algorithms, like the ones in OpenCV, and you aren't very keen on implementing them yourself, you might need to do some maneuvers like:
Test any of the OpenCV packages for Flutter/Dart in pub.dev. I can't recommend any as I never used them.
Use Method Channel calls to interact with OpenCV libraries for the native platforms (Android/iOS), passing the image and process it there and return it to Flutter afterwards.
Not ideal, but totally doable.

You can achieve same using remove.bg api. You can find more details on this thread.

First, you need to install Image package
Then use the following code to remove the background
import 'package:image/image.dart' as Img;
Future<Uint8List> removeWhiteBackgroundFromImage(
Uint8List bytes) async {
Img.Image image = Img.decodeImage(bytes);
Img.Image transparentImage = await _colorTransparent(image, 255, 255, 255);
var newPng = Img.encodePng(transparentImage);
return newPng;
}
Future<Img.Image> _colorTransparent(
Img.Image src, int red, int green, int blue) async {
var pixels = src.getBytes();
for (int i = 0, len = pixels.length; i < len; i += 4) {
if (pixels[i] == red && pixels[i + 1] == green && pixels[i + 2] == blue) {
pixels[i + 3] = 0;
}
}
return src;
}
Note: if you want to convert the image to Uint8List use the following code
Uint8List imageBytes = File(imageFilePath).readAsBytesSync();
Reference Link: https://gist.github.com/plateaukao/ebb5e7169dd89cc52bda338762d4997e

Related

Crop and save an image in Flutter without ui

I want to make an app that can crop image in a specific aspect ratio(device ratio).
But, i don't want any ui to show crop options.
Ok, here is an example,
If user tap on an image from the image list in the app the selected Image automatically (background process) crop (device ratio) & saved on the device without showing any crop related ui. How can i do this! Any function in dart by whom can crop an image without showing anything.
You can use copyCrop() with image:
Image copyCrop(Image src, int x, int y, int w, int h);
import 'dart:io';
import 'package:image/image.dart';
void main(List<String> argv) {
String path = argv[0];
Directory dir = Directory(path);
List files = dir.listSync();
List<int> trimRect;
for (var f in files) {
if (f is! File) {
continue;
}
List<int> bytes = f.readBytesSync();
Image image = decodeImage(bytes);
if (image == null) {
continue;
}
if (trimRect == null) {
trimRect = findTrim(image, mode: TrimMode.transparent);
}
Image trimmed = copyCrop(image, trimRect[0], trimRect[1],
trimRect[2], trimRect[3]);
String name = f.path.split(RegExp(r'(/|\\)')).last;
File('$path/trimmed-$name').writeBytesSync(encodeNamedImage(image, f.path));
}
}
I can confirm that Jim's answer is correct. Only thing I'd like to add to his answer is how to use the findTrim() method, which the docs don't explain properly. The key to use findTrim is to have an a sample image with target aspect ratio but it should also include base negative space as background. The findTrim() function basically takes information from a sample image and you can get the x,y coordinates as well as width,height if you don't want to manually calculate the x,y coordinates. The keyword here is negative space because if you just provide a target picture(say 4:3) to the findTrim() method, the function will simply crop the image from x,y coordinates which are 0,0 in this case. Having negative space that acts as place holder will make your work easier to clip the image.
For example to auto crop any 16:9 image to 4:3, have a 4:3 sample image with 16:9 negative space background. I have added the image as well which you can save to see for yourself.

How to add an image or text (Watermark) on a video/image - Flutter/Dart

I'm building a Flutter application which needs to add waermark on videos and images.
Is there any way to achieve this with firebase (or any other service)? I could do this on client-side but also there i can't find any flutter/Dart package related to video/image processing.
Kindly guide me how to do it.
Thanks
For videos:
https://github.com/tanersener/flutter-ffmpeg, though I couldn’t find anything that explicitly documents a way to edit the video, such as a watermark. But it should be possible according to others https://stackoverflow.com/a/57847155/6668797.
https://pub.dev/packages/video_manipulation
Adding still frames to an existing video, e.g. watermarks
.generateVideo(List<String> paths, String filename, int fps, double
speed).
Parameters paths list of input file paths. Can be images (.jpg or
.png) or video files (.mp4) that are used to generate the new video.
E.g.: ["documents/input.mp4", "documents/watermark.jpg]
For images:
https://pub.dev/packages/image
load, save and manipulate images in a variety of different file formats.
https://github.com/brendan-duncan/image/wiki/Examples
drawString(image, arial_24, 0, 0, 'Hello World');
As for other services, I don't know, but Firebase does not offer this service.
Otherwise, client/app-side, there’s currently not much else for videos, but there's more available for images, you can search https://pub.dev/flutter/packages?q=image+editor. However, for more options, you’ll have to seek out native Android/iOS libraries and custom integrate them through the platform channels.
For watermark images:
import 'package:extended_image/extended_image.dart';
import 'package:image/image.dart' as ui;
import 'package:path_provider/path_provider.dart';
Future<File> watermarkPicture( File picture, File watermark, String fileName) async {
ui.Image originalImage = ui.decodeImage(picture.readAsBytesSync());
ui.Image watermarkImage = ui.decodeImage((watermark.readAsBytesSync()));
ui.Image image = ui.Image(originalImage.width, originalImage.height);
ui.drawImage(image, watermarkImage);
// Easy customisation for the position of the watermark in the next two lines
final int positionX = (originalImage.width / 2 - watermarkImage.width / 2).toInt();
final int positionY = (originalImage.height - watermarkImage.height * 1.15).toInt();
ui.copyInto(
originalImage,
image,
dstX: positionX,
dstY: positionY,
);
final File watermarkedFile = File('${(await getTemporaryDirectory()).path}/$fileName');
await watermarkedFile.writeAsBytes(ui.encodeJpg(originalImage));
return watermarkedFile;
}
This is an customisation of this medium article. Because the original solution was not working for me.
For Image you can use this pacakge
https://pub.dev/packages/image_watermark
based on Image pacakge.
As parameter you have to pass image bytes and return output image bytes
and you can use Image.memory(imgBytes) widget.
Add text watermark:
var watermarkedImg = await image_watermark.addTextWatermarkCentered(imgBytes,'watermarkText');
you can customize position ,color of text
var watermarkedImg = await image_watermark.addTextWatermark(
imgBytes, ///image bytes
'watermarkText', ///watermark text
20, ///position of watermark x coordinate
30, ///y coordinate
color: Colors.green, ///default : Colors.white
)
Image watermark:
watermarkedImgBytes = await image_watermark.addImageWatermark(
imgBytes, //image bytes
imgBytes2,//watermark img bytes
imgHeight: 200, //watermark img height
imgWidth: 200, //watermark img width
dstY: 400,
dstX: 400);
For video:
https://pub.dev/packages/video_manipulation/example
_outputFilepath =
await VideoManipulation.generateVideo([inputVideopath,watermarkimgPath], outputFilename, framerate, speed);
To add image, Try this latest updated package video_watermark
VideoWatermark videoWatermark = VideoWatermark(
sourceVideoPath: videoPath,
watermark: Watermark(image: WatermarkSource.file(imagepath)),
onSave: (path){
// Get the output file path
},
);
videoWatermark.generateVideo();
I am not sure about adding watermark over video. But to help people who are looking for watermark over the image can refer to the simple article written by me.
Add Watermark over Image in Flutter
In this article, I have used Image package to apply watermark text or image over Image.There is well explained example program also written about this topic.

Is it possible to save a generated image in Codename One?

My question is related to this previous question. What I want to achieve is to stack images (they have transparency), write a string on top, and save the photomontage / photocollage with full resolution.
#Override
protected void beforeMain(Form f) {
Image photoBase = fetchResourceFile().getImage("Voiture_4_3.jpg");
Image watermark = fetchResourceFile().getImage("Watermark.png");
f.setLayout(new LayeredLayout());
final Label drawing = new Label();
f.addComponent(drawing);
// Image mutable dans laquelle on va dessiner (fond blanc)
Image mutableImage = Image.createImage(photoBase.getWidth(), photoBase.getHeight());
drawing.getUnselectedStyle().setBgImage(mutableImage);
drawing.getUnselectedStyle().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FIT);
// Paint all the stuff
paints(mutableImage.getGraphics(), photoBase, watermark, photoBase.getWidth(), photoBase.getHeight());
// Save the collage
Image screenshot = Image.createImage(photoBase.getWidth(), photoBase.getHeight());
f.revalidate();
f.setVisible(true);
drawing.paintComponent(screenshot.getGraphics(), true);
String imageFile = FileSystemStorage.getInstance().getAppHomePath() + "screenshot.png";
try(OutputStream os = FileSystemStorage.getInstance().openOutputStream(imageFile)) {
ImageIO.getImageIO().save(screenshot, os, ImageIO.FORMAT_PNG, 1);
} catch(IOException err) {
err.printStackTrace();
}
}
public void paints(Graphics g, Image background, Image watermark, int width, int height) {
g.drawImage(background, 0, 0);
g.drawImage(watermark, 0, 0);
g.setColor(0xFF0000);
// Upper left corner
g.fillRect(0, 0, 10, 10);
// Lower right corner
g.setColor(0x00FF00);
g.fillRect(width - 10, height - 10, 10, 10);
g.setColor(0xFF0000);
Font f = Font.createTrueTypeFont("Geometos", "Geometos.ttf").derive(220, Font.STYLE_BOLD);
g.setFont(f);
// Draw a string right below the M from Mercedes on the car windscreen (measured in Gimp)
g.drawString("HelloWorld",
(int) (848 ),
(int) (610)
);
}
This is the saved screenshot I get if I use the Iphone6 skin (the payload image is smaller than the original one and is centered). If I use the Xoom skin this is what I get (the payload image is still smaller than the original image but it has moved to the left).
So to sum it all up : why is the saved screenshot with Xoom skin different from the one I get with Iphone skin ? Is there anyway to directly save the graphics on which I paint in the paints method so that the saved image would have the original dimensions ?
Thanks a lot to anyone that could help me :-)!
Cheers,
You can save an image in Codename one using the ImageIO class. Notice that you can draw a container hierarchy into a mutable image using the paintComponent(Graphics) method.
You can do both approaches with draw image on mutable or via layouts. Personally I always prefer layouts as I like the abstraction but I wouldn't say the mutable image approach is right/wrong.
Notice that if you change/repaint a lot then mutable images are slower (this will not be noticeable for regular code or on the simulator) as they are forced to use the software renderer and can't use the GPU fully.
In the previous question it seems you placed the image with a "FIT" style which naturally drew it smaller than the containing container and then drew the image on top of it manually... This is problematic.
One solution is to draw everything manually but then you will need to do the "fit" aspect of drawing yourself. If you use layouts you should position everything based on the layouts including your drawing/text.

How do I procedurally generate images using rust-image?

I'd like to learn Rust and thought it would be fun to procedurally generate images. I've no idea where to start though... piston/rust-image? But even with that where should I begin?
The place to begin is the docs and the repository.
It's not immediately obvious from the landing page of the documentation, but the core type in image is ImageBuffer.
The new function allows one to construct an ImageBuffer representing an image with the given/width, storing pixels of a given type (e.g. RGB, or that with transparency). One can use methods like pixels_mut, get_pixel_mut and put_pixel (the latter are below pixels_mut in the documentation) to modify the image. E.g.
extern crate image;
use image::{ImageBuffer, Rgb};
const WIDTH: u32 = 10;
const HEIGHT: u32 = 10;
fn main() {
// a default (black) image containing Rgb values
let mut image = ImageBuffer::<Rgb<u8>>::new(WIDTH, HEIGHT);
// set a central pixel to white
image.get_pixel_mut(5, 5).data = [255, 255, 255];
// write it out to a file
image.save("output.png").unwrap();
}
which looks like:
The repo is particularly useful as a starting point, because it contains examples, in particular, it has an example of programmatically generating an image. When using a new library, I'll open the docs, and, if confused, the repo specifically to look for examples.
NOTE:
get_pixel_mut Deprecated since 0.24.0: Use get_pixel and put_pixel instead.
As #huon answer is 6 years old, I was getting errors reproducing the result, so I wrote this,
use image::{ImageBuffer, RgbImage};
const WIDTH:u32 = 10;
const HEIGHT:u32 = 10;
fn main() {
let mut image: RgbImage = ImageBuffer::new(WIDTH, HEIGHT);
*image.get_pixel_mut(5, 5) = image::Rgb([255,255,255]);
image.save("output.png").unwrap();
}

How to tell if an image is 90% black?

I have never done image processing before.
I now need to go through many jpeg images from a camera to discard those very dark (almost black) images.
Are there free libraries (.NET) that I can use? Thanks.
Aforge is a great image processing library. Specifically the Aforge.Imaging assembly.
You could try to apply a threshold filter, and use an area or blob operator and do your comparisons from there.
I needed to do the same thing. I came up with this solution to flag mostly black images. It works like a charm. You could enhance it to delete or move the file.
// set limit
const double limit = 90;
foreach (var img in Directory.EnumerateFiles(#"E:\", "*.jpg", SearchOption.AllDirectories))
{
// load image
var sourceImage = (Bitmap)Image.FromFile(img);
// format image
var filteredImage = AForge.Imaging.Image.Clone(sourceImage);
// free source image
sourceImage.Dispose();
// get grayscale image
filteredImage = Grayscale.CommonAlgorithms.RMY.Apply(filteredImage);
// apply threshold filter
new Threshold().ApplyInPlace(filteredImage);
// gather statistics
var stat = new ImageStatistics(filteredImage);
var percentBlack = (1 - stat.PixelsCountWithoutBlack / (double)stat.PixelsCount) * 100;
if (percentBlack >= limit)
Console.WriteLine(img + " (" + Math.Round(percentBlack, 2) + "% Black)");
filteredImage.Dispose();
}
Console.WriteLine("Done.");
Console.ReadLine();

Resources