I want to fill a credit card image with some text(name, surname,...) but i found problems to correctly find the starting position of the text.
I have marked my image with special pixels, I want to draw text at the start of this specific pixels but when I run the text is not aligned with them, I supposed that the specific pixel position that I calculated in the code is calculated starting from the first canvas pixel rather than the first bitmap pixel. How can I solve it? Thank you.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap bitmap = ((BitmapDrawable)this.getDrawable()).getBitmap();
final int w = bitmap.getWidth();
final int h = bitmap.getHeight();
int pixel;
int redValue;
int blueValue;
int greenValue;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
pixel = bitmap.getPixel(x, y);
redValue = Color.red(pixel);
blueValue = Color.blue(pixel);
greenValue = Color.green(pixel);
if (redValue == 255 && greenValue == 254 && blueValue == 0){
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(35);
canvas.drawText("Some Text", x, y, paint);
}
}
}
}
Related
So I want to draw two lines that cross in the middle (like an x), and I want to draw this onto my randomly generated bitmap. Does anyone know how I can make the line diagonl?
public static Bitmap randomImage(int width, int height) {
Bitmap ranImage = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Random rand = new Random(System.currentTimeMillis());
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++) {
int r = rand.nextInt(255);
int g = rand.nextInt(255);
int b = rand.nextInt(255);
int color = Color.rgb(r, g, b);
ranImage.setPixel(x, y, color);
}
//initialise a new canvas instance
Canvas canvas = new Canvas(ranImage);
//intialise a new paint instance to draw the line
Paint paint = new Paint();
//line color
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
//line width in pixels
paint.setStrokeWidth(3);
paint.setAntiAlias(true);
//set a pizel value to offset the line from the canvas edge
int offset = 50;
//draw a line on canvas at the center postion ....for now
canvas.drawLine(
offset,
canvas.getHeight()/2,
canvas.getWidth()-offset,
canvas.getHeight()/2,
paint
);
return ranImage;
}
How can I delete say 50px of the leftmost vertical column of a BufferedImage, and copy that into a new BufferedImage the same size as the original BufferedImage?
class TestCopyImage {
var img: BufferedImage? = null
private val rnd = Random()
fun create(screenWidth: Int, screenHeight: Int) {
img = BufferedImage(screenWidth, screenHeight, BufferedImage.TYPE_INT_RGB)
//Grab the graphics object off the image
val graphics = img!!.createGraphics()
//val stroke: Stroke = BasicStroke(1f)
//graphics.setStroke(stroke);
// Fill the image buffer
for (i in 1..screenWidth) {
for (j in 1..screenHeight) {
val r: Int = rnd.nextInt(255)
val g: Int = rnd.nextInt(255)
val b: Int = rnd.nextInt(255)
val randomColor = Color(r, g, b)
graphics.paint = randomColor
graphics.fill(Rectangle(i , j , 1, 1))
}
}
// Get a subimage, deleting 50 pixels of the left-most vertical portion.
img = img!!.getSubimage(50, 0, screenWidth - 50 , screenHeight)
// TODO Now copy that into a new image, same size as the original buffer?
img = BufferedImage(screenWidth, screenHeight, BufferedImage.TYPE_INT_RGB)
}
}
Here's a Java version of what you can do:
int panDist = 50;
BufferedImage subImg = img.getSubimage(panDist, 0, img.getWidth() - panDist, img.getHeight());
BufferedImage newImg = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
for (int x = 0; x < subImg.getWidth(); ++x) {
for (int y = 0; y < subImg.getHeight(); ++y) {
newImg.setRGB(x, y, subImg.getRGB(x, y));
}
}
The subimage isn't really necessary though, you could skip that and just do this instead:
int panDist = 50;
BufferedImage newImg = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
for (int x = panDist; x < img.getWidth(); ++x) {
for (int y = 0; y < img.getHeight(); ++y) {
newImg.setRGB(x - panDist, y, img.getRGB(x, y));
}
}
You could also tweak that slightly to modify the image in-place instead.
So Im still learning Java. Now Im learning JavaFX.
I have a picture of a tree. And I want to try two different method. the first method I use was using unary operator to turn the image colour to grey.
Now I want to try a second method using the ColourTransformer interface that I made to get a 10 pixel wide gray frame replacing the pixels on the border of an image.
This is what I have done. for the second method, im not quite sure how to specify the pixel. Any suggestions?
this is what I have done
public class ColourFilter extends Application {
//Using Unary Operator to transform image to grayscale - Method 1
public static Image transform(Image in, UnaryOperator<Color> f) {
int width = (int) in.getWidth();
int height = (int) in.getHeight();
WritableImage out = new WritableImage(
width, height);
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
out.getPixelWriter().setColor(x, y,
f.apply(in.getPixelReader().getColor(x, y)));
return out;
}
public static <T> UnaryOperator<T> compose(UnaryOperator<T> op1, UnaryOperator<T> op2) {
return t -> op2.apply(op1.apply(t));
}
//Using ColourTransformer interface to get 10 pixel wide gray frame replacing the pixels on the border of an image - Method 2
public static Image transform(Image in, ColourTransformer f) {
int width = (int) in.getWidth();
int height = (int) in.getHeight();
WritableImage out = new WritableImage(
width, height);
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
out.getPixelWriter().setColor(x, y, f.apply(x, y, in.getPixelReader().getColor(x, y)));
return out;
}
#FunctionalInterface
interface ColourTransformer {
Color apply(int x, int y, Color colorAtXY);
}
public void start(Stage stage) {
Image image = new Image("amazing-trees.jpg");
Image image2 = transform(image, Color::brighter);
Image image3 = transform(image2, Color::grayscale);
// alternative to two previous image transforms -- composition
//Image image3 = transform(image, compose(Color::brighter, Color::grayscale));
stage.setScene(new Scene(new VBox(
new ImageView(image),
// new ImageView(image2),
new ImageView(image3))));
stage.show();
}
}
As the compile error message says, you are trying to call
f.apply(Color);
where f is a ColourTransformer: however you defined the apply method in ColorTransformer with three parameters: apply(int, int, Color).
You need to replace
f.apply(in.getPixelReader().getColor(x, y))
with
f.apply(x, y, in.getPixelReader().getColor(x, y))
i.e.
public static Image transform(Image in, ColourTransformer f) {
int width = (int) in.getWidth();
int height = (int) in.getHeight();
WritableImage out = new WritableImage(
width, height);
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
out.getPixelWriter().setColor(x, y, f.apply(x, y, in.getPixelReader().getColor(x, y)));
return out;
}
You can get the 10-pixel gray border by doing:
Image image = new Image("amazing-trees.jpg");
int width = (int) image.getWidth();
int height = (int) image.getHeight();
Image framedImage = transform(image, (x, y, color) -> {
if (x < 10 || y < 10 || width - x < 10 || height - y < 10) {
return Color.GRAY ;
} else return color ;
});
I'm creating a method that takes two parameters with 2 indexes a start and an end that takes a location of the picture being edited and turn those pixels to a different color. Using a while loop to index start and end.
The problem I'm having is I'm only a getting a really small portion to change color:
Don't mind some of the code that is commented out. I was trying a bunch of different things.
public void negative(int start, int end)
{
Pixel[] pixelArray = this.getPixels(); //pixelarray index
Pixel pixel = null;
// int height = this.getHeight();
//int paintPoint = height / 2;
//int width = this.getWidth();
int i = 0;
int red, green, blue = 0;
// int x = 0;
Pixel topPixel = null;
Pixel bottomPixel = null;
//int startY;
//int startX;
int y = start;
int x = end;
//int count;
while( y < this.getHeight())
{
y++;
while (x < this.getWidth()) //loops through index
{
pixel = this.getPixel(x,y);
red = pixel.getRed();
green = pixel.getGreen();//collects color green
blue = pixel.getBlue();//collects color blue
Color negColor = new Color( 255 - red, 255 - green, 255 - blue);//sets new values of pixels
pixel.setColor(negColor);
x++;
//count = count + 1;
i++;//indexes continuing
}
}
}
A picture is 2D yet you are treating it as 1D (notice after once through your inner x loop it never is reset to its min value). If you wish to color an arbitrary rectangle within a given photo the parms should include two points : minx, miny and maxx maxy then your pair of 2D loops visits each point in that region line by line.
// do sanity checks on your parms
if (this.getWidth() < maxx) {
maxx = this.getWidth();
}
if (this.getHeight() < maxy) {
maxy = this.getHeight();
}
if (minx < 0) {
minx = 0;
}
if (miny < 0) {
miny = 0;
}
for (y = mixy; y < maxy; y++) {
for (x = mixx; x < maxx; x++) {
// now your have valid x and y values
}
}
I know how to get the RGB values of individual pixels of a bitmap. How can I get the average RGB value for all of the pixels of a bitmap?
I think below code for exact answer to you.
Get the Average(Number of pixels)of Red, Green and Blue value for the given bitmap.
Bitmap bitmap = someBitmap; //assign your bitmap here
int redColors = 0;
int greenColors = 0;
int blueColors = 0;
int pixelCount = 0;
for (int y = 0; y < bitmap.getHeight(); y++)
{
for (int x = 0; x < bitmap.getWidth(); x++)
{
int c = bitmap.getPixel(x, y);
pixelCount++;
redColors += Color.red(c);
greenColors += Color.green(c);
blueColors += Color.blue(c);
}
}
// calculate average of bitmap r,g,b values
int red = (redColors/pixelCount);
int green = (greenColors/pixelCount);
int blue = (blueColors/pixelCount);
The answer from john sakthi does not work correctly if the Bitmap has transparency (PNGs). I modified the answer for correctly getting the red/green/blue averages while accounting for transparent pixels:
/**
* Calculate the average red, green, blue color values of a bitmap
*
* #param bitmap
* a {#link Bitmap}
* #return
*/
public static int[] getAverageColorRGB(Bitmap bitmap) {
final int width = bitmap.getWidth();
final int height = bitmap.getHeight();
int size = width * height;
int pixelColor;
int r, g, b;
r = g = b = 0;
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
pixelColor = bitmap.getPixel(x, y);
if (pixelColor == 0) {
size--;
continue;
}
r += Color.red(pixelColor);
g += Color.green(pixelColor);
b += Color.blue(pixelColor);
}
}
r /= size;
g /= size;
b /= size;
return new int[] {
r, g, b
};
}
you can use this method for this purpose: Bitmap.createBitmap
For instance:
int[] colors = new int[yourWidth * yourHeight];
Arrays.fill(colors, Color.Black);
Bitmap bitamp = Bitamp.createBitmap(colors, yourWidth, yourHeight, Bitmap.Config.ARGB_8888);
Check for typo