In my app I am trying to create watermarks on the image when either user captures it from camera or uploads from gallery. but the problem is that when I draw text on the canvas(Which is my image itself). I get different results every time.
I want to show 3 texts vertically in center, 3 texts vertically at left and 1 logo at right. I want the watermarks in such way that. if user captures the image from camera or browse through gallery. The texts and logo(watermarks) should be remain of same size and clearly visible, irrespective of the image size or pixel density.
Can anyone show me how to achieve this. I tried Bitmap and Canvas but I am getting different text sizes and blurred text and everything different on different images.
In the below images, here is my problem.
1.Image which was clicked from camera but I used it from browse images
2.Image which was selected form Capture Image button
3.random low quality image from gallery
Here is the code
Glide.with(getApplicationContext())
.load(uri)
.asBitmap()
.into(new SimpleTarget<Bitmap>(200, 100) {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
//this is the required bitmap
pikedPhoto = resource.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(pikedPhoto);
Paint paintCenter = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
paintCenter.setStyle(Paint.Style.FILL);
paintCenter.setColor(getResources().getColor(android.R.color.black)); // Text Color
paintCenter.setColor(Color.RED);
//float size = convertDpToPx(context, 25);
//paintCenter.setTextSize(size); //Text Size
paintCenter.setTextAlign(Paint.Align.CENTER);
float textY= pikedPhoto.getHeight();
float textX= pikedPhoto.getWidth()/2;
String text1 = "Centre Text";
canvas.drawText(text1,textX,textY,paintCenter);
canvas.drawText(text1,textX,textY-10,paintCenter);
canvas.drawText(text1,textX,textY-20,paintCenter);
String text2 = "Left Text";
Paint paintLeft = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
paintLeft.setStyle(Paint.Style.FILL);
paintLeft.setColor(getResources().getColor(android.R.color.black)); // Text Color
paintLeft.setColor(Color.RED);
//float sizeLeft = convertDpToPx(context, 25);
//paintLeft.setTextSize(sizeLeft); //Text Size
paintLeft.setTextAlign(Paint.Align.LEFT);
float textYL= pikedPhoto.getHeight();
canvas.drawText(text2,0,textYL,paintLeft);
canvas.drawText(text2,0,textYL-10,paintLeft);
canvas.drawText(text2,0,textYL-20,paintLeft);
// in this case, center.x and center.y represent the coordinates of the center of the rectangle in which the text is being placed
//canvas.drawBitmap(logo, (pikedPhoto.getWidth()) / 4, 250, new Paint());
img.setImageBitmap(pikedPhoto);
}
});
Related
I have an image saved in my database that is passed to an image as a byte array and then loaded to the Image view. However, I can't get it to fill the imageView. I use the following code:
package com.example.AppPrototipo.ui.tourist;
imports...
#Component
public class ExperienceController {
#FXML
Pane imagePane;
#FXML
ImageView imageViewPrincipal;
private final ExperienceRepository experienceRepository;
public ExperienceController(ExperienceRepository experienceRepository) {
this.experienceRepository = experienceRepository;
}
#FXML
private void initialize(){
Experience experience = experienceRepository.findById(1);
Image image = new Image(new ByteArrayInputStream(experience.getImages().get(0).getImageData()));
imageViewPrincipal.setImage(image);
imageViewPrincipal.fitWidthProperty().bind(imagePane.widthProperty());
imageViewPrincipal.fitHeightProperty().bind(imagePane.heightProperty());
}
}
This is the result i get:
The desired result would be that the image fills the whole width (fill the black side) by cropping the top and bottom sides and remaining centered. Would anyone be able to help me?
Assuming you're setting the preserveRatio property to true on the ImageView, and as matt stated is his comment, you only need to set one of them, say fitWidth, and the fitHeight will be calculated using the image ratio.
the problem is that the ratios of the image and the pane don't match so you need to do some cropping using setViewport, and it would be best to do the cropping when the pane's height or width change.
What you need to do is to calculate the ratio of the image, and compare it to the ratio of the pane, the comparison will let you decide whether to keep the original width or original height of the image, and you'll calculate the other using the pane's ratio.
Not really sure if that's the best practice but here's the code for what i have described
double oldImageWidth = image.getWidth(), oldImageHeight = image.getHeight(); //saving the original image size and ratio
double imageRatio = oldImageWidth / oldImageHeight;
imageViewPrincipal.setImage(image);
ChangeListener<Number> listener = (obs, ov, nv) -> {
double paneWidth = imagePane.getWidth();
double paneHeight = imagePane.getHeight();
double paneRatio = paneWidth / paneHeight; //calculating the new pane's ratio
//after width or height changed
double newImageWidth = oldImageWidth, newImageHeight = oldImageHeight;
if (paneRatio > imageRatio) {
newImageHeight = oldImageWidth / paneRatio;
} else if (paneRatio < imageRatio) {
newImageWidth = oldImageHeight * paneRatio;
}
imageViewPrincipal.setViewport(new Rectangle2D( // The rectangle used to crop
(oldImageWidth - newImageWidth) / 2, (oldImageHeight - newImageHeight) / 2, //MinX and MinY to crop from the center
newImageWidth, newImageHeight) // new width and height
);
imageViewPrincipal.setFitWidth(paneWidth);
};
imagePane.widthProperty().addListener(listener);
imagePane.heightProperty().addListener(listener);
And here is how it looks
i want to creat an android app
that shows all pixels of an image but when i zoom color of the corners of the pixels blend with other pixels around it i want pixels to show their color perfectly in their squares
( like pixel art or ms paint when you zoom it)
i tried drawing a rectangle on canvas and drawing a bitmap 1×1
with color what i want but it blends
here is a picture and code
upper pic 4×4 what it creates
lower pic what i want
try{
//creating bitmap from other for background
bt2 = Bitmap.createBitmap(bt,i2,i3,i,i);
}
Canvas c=new Canvas(bt2);
c.drawColor(Color.argb(255,255,255,255));
//creating 1×1 image
Bitmap bt3 = Bitmap.createBitmap(bt,0,0,1, 1 );
//blue color to draw for pixel looking
Canvas c2 =new Canvas(bt3);
c2.drawColor(Color.argb(255,0,0,255));
int w=bt2.getWidth();
int h= bt2.getHeight();
//geting pixels so i would use it
btpixels=new int [w*h];
bt2.getPixels(btpixels,
0,w,0,0,w,h );
int j =0;
Paint paint =new Paint();
for(j=0;j<w;j++)
{
paint.setARGB(255,0,255,0);
//drawing blue bitmap on bt2
c.drawBitmap(bt3,j,j,paint) ;
//paint.setColor( btpixels[j]);
/* c.drawRect(
(float)i-1,
(float) i-1,
(float)i,
(float)i,
paint ); */
}
img.setImageBitmap( bt2 );
}catch(IllegalArgumentException e){ }
i understood how to stop pixels from blending. I was using 2×2 image on the screen 300ppi . If i want to show 1 pixel per inch i should use pixel bitmap(here bt3) width as 300
best would be
width of the pixel square =
width of the screen / num of pixels
I tried everything I found to save just my image without borders without success.
My image is 124x126, so when the image is saved it's always with borders and new size 300x300, If I use another program to select only my image it's 208x209.
so I don't know why my image is scaled and why it's always 300x300, If I change the size of vtkRenderWindow to 124x126 the borders are still there and my image is shrunk.
My question is how I can save my image of 124x126 without borders?
mapper.SetInputConnection(polyDataReader.GetOutputPort());
vtkActor actor = new vtkActor();
actor.SetMapper(mapper);
actor.GetBounds(bounds);
System.out.println("actor: " + bounds[1] + " x " + bounds[3]); // 124x126 (everything's ok)
//Create a renderer, render window, and interactor
vtkRenderer renderer = new vtkRenderer();
vtkRenderWindow renderWindow = new vtkRenderWindow();
renderWindow.BordersOff(); // the borders are still there
renderWindow.AddRenderer(renderer);
vtkRenderWindowInteractor renderWindowInteractor = new vtkRenderWindowInteractor();
renderWindowInteractor.SetRenderWindow(renderWindow);
//Add the actor to the scene
renderer.AddActor(actor);
renderer.SetBackground(0, 0, 0);
//Render and interact
renderWindow.Render();
//screenshot code:
vtkWindowToImageFilter w2if = new vtkWindowToImageFilter();
w2if.SetInput(renderWindow);
w2if.Update();
vtkPNGWriter writer = new vtkPNGWriter();
writer.SetFileName("out.png"); //my image with borders 300x300 !!!!??
writer.SetInputData(w2if.GetOutput());
writer.Write();
ps: sorry for my English
It is because your renderwindow has the default size of 300x300.
What you have to realize is that the polydata is rendered in a 3D scene, and what you call "borders" is the background, the amount of which depends on the zoom level, i.e. on your camera's position. To get what you want, you need to do two things:
Resize renderwindow to desired image size:
renderWindow.SetSize(bounds[1], bounds[3]);
Reposition camera so that the actor fills the viewport completely. Try
renderer.GetActiveCamera().SetParallelScale(1); // we want parallel projection
renderer.GetActiveCamera().SetParallelScale(0.5 * (bounds[3] - bounds[2])); // zoom
The bounds in zoom may be 0.5 * (bounds[1] - bounds[0]), not exactly sure which side of the rectangle it should be.
Hope this helps,
Miro
I have an Android app that loads an image as a bitmap and displays it in an ImageView. The problem is that the image appears to have a transparent background; this causes some of the black text on the image to disappear against the black background.
If I set the ImageView background to white, that sort of works, but I get ugly big borders on the image where it is stretched to fit the parent (the actual image is scaled in the middle).
So - I want to convert the transparent pixels in the Bitmap to a solid colour - but I cannot figure out how to do it!
Any help would be appreciate!
Thanks
Chris
If you are including the image as a resource, it is easiest to just edit the image yourself in a program like gimp. You can add your background there, and be sure of what it is going to look like and don't have use to processing power modifying the image each time it is loaded.
If you do not have control over the image yourself, you can modify it by doing something like, assuming your Bitmap is called image.
Bitmap imageWithBG = Bitmap.createBitmap(image.getWidth(), image.getHeight(),image.getConfig()); // Create another image the same size
imageWithBG.eraseColor(Color.WHITE); // set its background to white, or whatever color you want
Canvas canvas = new Canvas(imageWithBG); // create a canvas to draw on the new image
canvas.drawBitmap(image, 0f, 0f, null); // draw old image on the background
image.recycle(); // clear out old image
You can loop through each pixel and check if it is transparent.
Something like this. (Untested)
Bitmap b = ...;
for(int x = 0; x<b.getWidth(); x++){
for(int y = 0; y<b.getHeight(); y++){
if(b.getPixel(x, y) == Color.TRANSPARENT){
b.setPixel(x, y, Color.WHITE);
}
}
}
i want my Bitmap that has the height of the screen and has a bigger width than the screen to be moved a little bit to the right or left if the user changes the desktop so he can see the entire image.
Here is my code that just works partially:
int x = -1*(int)((xOffset*bmp.getWidth()));
canvas.drawBitmap(bmp, x, 0, null);
thank you!
You get exact pixel values via the variables xPixels and yPixels in onOffsetsChanged(). See my answer here: android live wallpaper rescaling
For example, in onOffsetsChanged(), you can set a private class variable
mPixels = xPixels;
Then, in your draw routine
holder = getSurfaceHolder();
c = holder.lockCanvas();
c.translate(mPixels, 0f);
// c.drawBitmap ... goes here :-)
Typically, you will want a bitmap twice the width of your screen, with your artwork centered in the middle. For example: 320 pixel width screen -> 640 pixel width bitmap with "center" from 160 to 480. mPixels will be 0 at the left most launcher screen (of 5), -160 at the center, and -320 at the rightmost screen.