flutter canvas custom transparent - flutter

Is there a way to choose a color to be replaced for transparent when painting an image to the Flutter canvas? I have a spritesheet with magenta background and I want it to be transparent when painted. I am painting in the following way:
void _draw(Canvas canvas, Offset offset, ui.Image image) {
final paint = Paint();
canvas.drawImage(image, offset, paint);
}

You just need to set an ARGB color with the alpha value
paint.color = Color.fromARGB(alpha, r, g, b)
Where alpha is a double between 0 and 1, 0 being transparent and 1 the most visible. R,G,B is the level of red blue green colors applied.
The white color is:
r=255, g=255, b=255
The black color is:
r=0, g=0, b=0
So in your case:
paint.color = Color.fromARGB(0, 0, 0, 0)

Related

How to draw a circle filled with lines in Flutter

I am using canvas to draw circles in flutter, is there any easy way to draw circles filled with lines?
PS:I know I can calculate each line's points then drawing lines in circle. But is there any simple method that can be implemented without calculation?
This is what I want to achieve:
Finally, I found an easy and ingenious solution without calculation.
That is creating a linear gradient filled in the circle.
give two colors for the start and end of the gradient.
give transparent to the start color.
give the actual line color to the end color.
Paint paint = new Paint();
paint.color =Colors.red;
paint.style = PaintingStyle.fill;
paint.shader = ui.Gradient.linear(
start,
//the line interval is 20
Offset(start.dx + 20, start.dy),
[
//give transparent to start color, give actual line color to the end color
Colors. transparent,
Colors.red
],
//The interval [0.0,0.9] is transparent, and the interval [0.9,1.0] is red. So it looks like drawing red lines
[0.90, 1.0],
//just repeat the gradient
TileMode.repeated,
null);
canvas.drawCircle(
Offset(centerX, centerY),
radius,
paint);

Flutter CustomPaint Moving a circle along a path

I'm learning CustomPaint by making my own line chart. I have already made the chart itself so now i'm making the things around it. One them is a trackball/line whenever you pan. So far i've made the dashed line from top to bottom, and it works perfectly, now i want to make the the ball that's gonna follow along with the line. My problem is getting the ball and dashed line to always be in sync. right now it's the dashed line that follows my finger and the ball that does'nt match up. I found this answer on stack overflow but it's not working quite right for me. This video is how it currently functions with the following code,
where dragX is the current x-axis position of your finger in pixels.
void drawTrackballLine(Canvas canvas, Size size) {
double dashHeight = 5;
double dashSpace = trackBallOptions.dashSpacing;
double y = 0;
final paint = Paint()
..color = trackBallOptions.color
..strokeWidth = trackBallOptions.strokeWidth;
while (y < size.height) {
canvas.drawLine(
Offset(dragX, y),
Offset(dragX, y + dashHeight),
paint,
);
y += dashSpace + dashHeight;
}
}
void drawTrackball(Canvas canvas, Size size, Path path) {
final pathMetric = path.computeMetrics().elementAt(0);
final value = pathMetric.length * (dragX / size.width);
final pos = pathMetric.getTangentForOffset(value);
canvas.drawCircle(pos!.position, 5, Paint());
}

In Flutter, is it possible to draw an image with a replaced color and opacity?

I have a grey image. I want to draw it using a color but with opacity to a canvas. By using Color Filter, I was able to draw it on the canvas by replacing the color. If I adjust the alpha value, it changes image opacity (partial grey/red). The following code snippet shows how to draw a grey image as red onto a canvas. But how can I draw the red image as transparent to the canvas?
static void drawBrushDetail(Canvas canvas, double cx, double cy, double brushSize, double imageAngleRad) {
canvas.translate(cx + brushSize / 2, cy + brushSize / 2);
ui.Image bt = imgBrushTip; //this is a gray image
Color selectedColor = getDrawColor(cx,cy);
final _paint = Paint();
var alphaVal=255;
//if I change alphaVal to 100, the final draw looks more gray instead of red with 100 Alpha
_paint.colorFilter = ColorFilter.mode(selectedColor.withAlpha(alphaVal), BlendMode.srcATop);
if (imageAngleRad != 0.0) canvas.rotate(imageAngleRad);
canvas.translate(-brushSize / 2, -brushSize / 2);
// draw image with specified brushSize
canvas.drawImageRect(bx, Rect.fromLTRB(0, 0, bt.width, bt.height),
Rect.fromLTRB(0, 0, brushSize, brushSize), _paint);
//traslate back, don't want to use save and restore layer since it's expensive
canvas.translate(brushSize / 2, brushSize / 2);
if (imageAngleRad != 0.0) canvas.rotate(-imageAngleRad);
canvas.translate(-cx - brushSize / 2, -cy - brushSize / 2);
}
See the image below. The above code will paint the image with solid red color. (image pointed by the red arrow). But I want the result to be an image with red color and transparent. Since in Flutter, there is no API to set alpha for canvas, don't know if it is possible.
I figured it out but the credit goes to pskink
I only need to draw one image(gray color) but I need to do the followings:
Resize and rotate the image.
Replace the gray image with red color.
Draw the image (now in red) with opacity.
Here is the code snippet.
static void drawBrushDetail1(Canvas canvas, double cx, double cy, double size) {
final _paint = Paint();
const opacity = 0.5;
_paint.color = Color.fromRGBO(0, 0, 0, opacity);
ui.Image bx = uiImg[0];
double scale = size / 60; //size is brush tip size and 60x60 is gray image size
canvas.drawAtlas(
bx,
[
RSTransform.fromComponents(
rotation: imageAngleRad,
scale: scale,
anchorX: 30,
anchorY: 30,
translateX: cx,
translateY: cy)
],
[
/* The size of gray image is 60 x 60 */
const Rect.fromLTWH(0, 0, 60, 60)
],
[Colors.red],
BlendMode.dstIn, /*This is replace the gray image wiht red color
null /* No need for cullRect */,
_paint); //_paint will paint the red image in 0.5 opacity
}

How to change a gray scale image to red colored image?

I have an image of a thick wave which changes from black to white smoothly like the black slowly changes from dark to white. How can I change this image to red instead of having different shades of black I need different shades of red going from dark red to white.
Create an array of size (rows,cols,3) where (rows,cols) is the size of gray image. Make its red channel equal to 255 and other channels equal to gray image
img = imread('moon.tif');
[r,c,z] = size(img);
red_img = uint8(zeros(r,c,3));
red_img(:,:,1) = 255;
red_img(:,:,2) = img;
red_img(:,:,3) = img;
subplot(1,2,1);
imshow(img,[]);
subplot(1,2,2);
imshow(red_img,[]);

Accurately get a color from pixel on screen and convert its color space

I need to get a color from a pixel on the screen and convert its color space. The problem I have is that the color values are not the same when comparing the values against the Digital Color Meter app.
// create a 1x1 image at the mouse position
if let image:CGImage = CGDisplayCreateImage(disID, rect: CGRect(x: x, y: y, width: 1, height: 1))
{
let bitmap = NSBitmapImageRep(cgImage: image)
// get the color from the bitmap and convert its colorspace to sRGB
var color = bitmap.colorAt(x: 0, y: 0)!
color = color.usingColorSpace(.sRGB)!
// print the RGB values
let red = color.redComponent, green = color.greenComponent, blue = color.blueComponent
print("r:", Int(red * 255), " g:", Int(green * 255), " b:", Int(blue * 255))
}
My code (converted to sRGB): 255, 38, 0
Digital Color Meter (sRGB): 255, 4, 0
How do you get a color from a pixel on the screen with the correct color space values?
Update:
If you don’t convert the colors colorspace to anything (or convert it to calibratedRGB), the values match the Digital Color Meters values when it’s set to “Display native values”.
My code (not converted): 255, 0, 1
Digital Color Meter (set to: Display native values): 255, 0, 1
So why when the colors values match the native values in the DCM app, does converting the color to sRGB and comparing it to the DCM's values(in sRGB) not match? I also tried converting to other colorspaces and there always different from the DCM.
OK, I can tell you how to fix it/match DCM, you'll have to decide if this is correct/a bug/etc.
It seems the color returned by colorAt() has the same component values as the bitmap's pixel but a different color space - rather than the original device color space it is a generic RGB one. We can "correct" this by building a color in the bitmap's space:
let color = bitmap.colorAt(x: 0, y: 0)!
// need a pointer to a C-style array of CGFloat
let compCount = color.numberOfComponents
let comps = UnsafeMutablePointer<CGFloat>.allocate(capacity: compCount)
// get the components
color.getComponents(comps)
// construct a new color in the device/bitmap space with the same components
let correctedColor = NSColor(colorSpace: bitmap.colorSpace,
components: comps,
count: compCount)
// convert to sRGB
let sRGBcolor = correctedColor.usingColorSpace(.sRGB)!
I think you'll find that the values of correctedColor track DCM's native values, and those of sRGBcolor track DCM's sRGB values.
Note that we are constructing a color in the device space, not converting a color to the device space.
HTH