Copy An Image to A Specific Coordinate - java

I have a program that works well; however, I want to be able to copy an earth image to a different section of the new image that is created. For example, if I could place the picture of the Earth on the bottom left corner instead of the top left corner.
import java.awt.*;
public class CopyCatDemo
{
public static void main(String[] args)
{
Picture sourcePicture = new Picture("earth.jpg");
System.out.println("Width: " + sourcePicture.getWidth());
System.out.println("Height: " + sourcePicture.getHeight());
Picture targetPicture1 = new Picture(800,800);
targetPicture1.setAllPixelsToAColor(Color.BLACK);
Pixel sourcePixel, targetPixel = null;
Color sourceColor, targetColor = null;
for(int y = 0; y < sourcePicture.getHeight(); y++)
{
for(int x = 0; x < sourcePicture.getWidth(); x++)
{
sourcePixel = sourcePicture.getPixel(x,y);
sourceColor = sourcePixel.getColor();
targetPixel = targetPicture1.getPixel(x,y);
targetPixel.setColor(sourceColor);
}
}
sourcePicture.show();
targetPicture1.show();
targetPicture1.write("NewFile.jpg");
}//end of main method
}//end of class
So, if someone could please demonstrate how to edit this code to get the picture of the Earth to appear on the bottom left corner as an example on the new target image that would be appreciated! Thanks!

if I could place the picture of the Earth on the bottom left corner instead of the top left corner.
Do the proper math to offset the coordinates - for example to move to the bottom left you need to vertically offset the target pixel - in other words offset the y value for the target pixel by the height of the target minus the height of the source
int vOffset = targetPicture1.getHeight() - sourcePicture.getHeight();
//
targetPixel = targetPicture1.getPixel(x, vOffset + y);

Related

Android, erasing tool in a drawing application

I'm developing a note application and I want that the user can delete lines with the eraser tool. The eraser is built with a square that if positioned above a line, that line is completely removed. I've tried a lot of solutions, most are summarized here: Android: How to check if a rectangle contains touched point?.
The solution with path.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)) is working but acts more like a white brush, but I want that all the line is removed.
I've found a solution but I have this problem and I don't know why. Essentially the line is not always removed, it depends on where the user clicks (maybe for lack of precision?). In the example above, if the user click on the green area, the line is removed, if the user click on the red square it is not removed.
The logic is: I take a lot of points from the path and if there's one point that is inside RectF, the line is removed.
private RectF rectF = new RectF();
private void erase(float x, float y) {
int areaLength = 40;
rectF.set(x - areaLength, y - areaLength, x + areaLength, y + areaLength);
Log.d("rectf", rectF.toString());
for (int i = 0; i < lines.size(); i++) {
Stroke line = lines.get(i);
PathMeasure pm = new PathMeasure(line, false);
for (float distance = 0; distance < 1.1; distance += 0.1) {
float[] pointCoordinates = new float[2];
boolean found = pm.getPosTan(pm.getLength() * distance, pointCoordinates, null);
if(!found) continue;
if(rectF.contains(pointCoordinates[0], pointCoordinates[1])) {
lines.remove(i);
break;
}
}
}
}
x and y are the coordinates of the user click and Stroke is a subclass of Path.

MPAndroid : How to place the text inside the circle (without y-offset)

I am developing a small chart app to monitor the blood sugar with the MPAndroidChart library.
Is there a way to draw the text inside the circle without offset?
As suggested in another post, i put in a slight y-offset (different y-data for circle and text) and achieved a result which is ok.
But if there are only two values the text and circle do not align.
I am not that familiar with modifying the yAxis Renderer, do you know how to find the formula behind the offset for the labels? (would be great to just recalculate it..)
Similar problem: How to place the text values inside in MPAndroidChart circle?
With manual offset between text and circle y-data
Due to zooming in on y-axis (less data points and range on y-axis) the manuel offset is not working well here..
Otherwise awesome library PhilJay !!
EDIT: I have found a easy and sufficient solution:
Override the drawValues method from LineChartRenderer**
In LineChartRenderer.java -> drawValues the text is vertically shifted by this line:
drawValue(c, formatter.getPointLabel(entry), x, y - valOffset, dataSet.getValueTextColor(j / 2));
So to get rid of the "- valOffset":
1.Override the drawValues method
Create a new java file "CenteredTextLineChartRenderer.java" and override method drawValues from LineChartRenderer
2.Modify the y-valOffset to y+textHeight*0.35f
Add float textHeight = dataSet.getValueTextSize();
public class CenteredTextLineChartRenderer extends LineChartRenderer {
public CenteredTextLineChartRenderer(LineDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
super(chart, animator, viewPortHandler);
}
//Modified drawValues Method
// Center label on coordinate instead of applying a valOffset
#Override
public void drawValues(Canvas c) {
if (isDrawingValuesAllowed(mChart)) {
List<ILineDataSet> dataSets = mChart.getLineData().getDataSets();
for (int i = 0; i < dataSets.size(); i++) {
ILineDataSet dataSet = dataSets.get(i);
float textHeight = dataSet.getValueTextSize();
if (!shouldDrawValues(dataSet) || dataSet.getEntryCount() < 1)
continue;
// apply the text-styling defined by the DataSet
applyValueTextStyle(dataSet);
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
// make sure the values do not interfear with the circles
int valOffset = (int) (dataSet.getCircleRadius() * 1.75f);
if (!dataSet.isDrawCirclesEnabled())
valOffset = valOffset / 2;
mXBounds.set(mChart, dataSet);
float[] positions = trans.generateTransformedValuesLine(dataSet, mAnimator.getPhaseX(), mAnimator
.getPhaseY(), mXBounds.min, mXBounds.max);
ValueFormatter formatter = dataSet.getValueFormatter();
MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
for (int j = 0; j < positions.length; j += 2) {
float x = positions[j];
float y = positions[j + 1];
if (!mViewPortHandler.isInBoundsRight(x))
break;
if (!mViewPortHandler.isInBoundsLeft(x) || !mViewPortHandler.isInBoundsY(y))
continue;
Entry entry = dataSet.getEntryForIndex(j / 2 + mXBounds.min);
if (dataSet.isDrawValuesEnabled()) {
//drawValue(c, formatter.getPointLabel(entry), x, y - valOffset, dataSet.getValueTextColor(j / 2));
drawValue(c, formatter.getPointLabel(entry), x, y+textHeight*0.35f, dataSet.getValueTextColor(j / 2));
}
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
Drawable icon = entry.getIcon();
Utils.drawImage(
c,
icon,
(int)(x + iconsOffset.x),
(int)(y + iconsOffset.y),
icon.getIntrinsicWidth(),
icon.getIntrinsicHeight());
}
}
MPPointF.recycleInstance(iconsOffset);
}
}
}
}
3.Set your own LineChart renderer to your modified drawValues class
LineChart mChart = (LineChart) mainActivity.findViewById(R.id.LineChart);
mChart.setRenderer(new CenteredTextLineChartRenderer(mChart,mChart.getAnimator(),mChart.getViewPortHandler()));
Run your code and manually adapt the 0.35f offset in your CenteredTextLineChartRenderer class
Now your text is always vertically centered!
IMPORTANT: With deleting the valOffset your label is not vertically centered as the text anchor is not in the center of your text label. So you have to insert a manual offset "textHeight*0.35f" (just try it out).

How to get pixels inside of a quadrilateral defined by four points in OpenCV?

I'm new to OpenCV, but with a bit of luck and a lot of time I was able to hack together some code that detects individual cells in a chessboard like so:
The image frame is being stored in a Mat and the corners are being stored in a MatOfPoint2f.
Code to show how I'm using the matrices to draw the cells individually:
private void draw(final Mat frame) {
for (int x = 0; x < BOARD_SIZE - 1; x++)
for (int y = 0; y < BOARD_SIZE - 1; y++) {
final int index = x + y * BOARD_SIZE;
final Point topLeft = cornerPoints.get(index);
final Point bottomLeft = cornerPoints.get(index + BOARD_SIZE);
final Point topRight = cornerPoints.get(index + 1);
final Point bottomRight = cornerPoints.get(index + 1 + BOARD_SIZE);
// left line
Imgproc.line(frame, topLeft, bottomLeft, DEBUG_COLOR);
// right line
Imgproc.line(frame, topRight, bottomRight, DEBUG_COLOR);
// top line
Imgproc.line(frame, topLeft, topRight, DEBUG_COLOR);
// bottom line
Imgproc.line(frame, bottomLeft, bottomRight, DEBUG_COLOR);
}
}
How would I use the four points (the corners of the cells) to get the RGB values of the pixels inside of the each quadrilateral?
Create a mask from your vertices. You can use fillPoly for that.
Then iterate over pixels. If pixel(x,y) is valid in your mask, read RGB else continue. Restrict pixel iteration range using your extreme vertices.
Masking works. If you have lots of polygons, or not too much RAM, a point-in-polygon test may be more efficient, especially if you can guarantee that your quadrilaterals are convex. See this reference

Swing drawing sometimes works

I'm trying to draw functions using Java Swing and AWT. The problem is not always all of the 300 points of the graph are drawn. When I loop over the first points of the graph in debug mode, there is much more change the graph is drawn completely. I use the following code to create a JFrame and set the graphics object to the class member g.
jFrame = new JFrame();
jFrame.setSize(WIDTH, HEIGHT);
jFrame.setVisible(true);
g = jFrame.getContentPane().getGraphics();
Then I call this method for every function I want to draw.
private void drawGraph(IGraph graph, Bounds bounds, Ratios ratios) {
//contains visual information about the graph
GraphVisuals visuals = graph.getVisuals();
g.setColor(visuals.color);
//the previous point is remembered, to be able to draw a line from one point to the next
int previousXi = 0;
int previousYi = 0;
//a loop over every point of the graph. The graph object contains two arrays: the x values and the y values
for (int i = 0; i < graph.getSize(); ++i) {
//calculate the x value using the ratio between the graph's size on the x-axis and the window size and the starting point on the x-axis
int xi = (int) (ratios.xRatio * (graph.getX(i) - bounds.xMin) + 0.5);
//analogous for the y axis
int yi = HEIGHT - (int) (ratios.yRatio * (graph.getY(i) - bounds.yMin) + 0.5);
//draw
if (visuals.hasBullets) {
g.fillOval(xi, yi, visuals.bulletSize, visuals.bulletSize);
}
if (visuals.hasLine) {
if (i != 0) {
g.drawLine(previousXi, previousYi, xi, yi);
}
}
previousXi = xi;
previousYi = yi;
}
}

color tracking using webcam feed

I am trying to create a color tracking bird flock, using live video from my webcam. I was instructed to use a constructor to create an array of .gifs that could work independently and follow a specific color around the video.
I did some research and this is as far as I got. Now I am getting an error that I don't really understand. For a very early dummy example of the intentions i have with the code, please see this .gif: Flock of birds
import processing.video.*;
import gifAnimation.*;
video = new Movie(); /// This is the line that gives me the error
// class
Birdy [] arrayOfBirds;
int numberOfBirds = 10;
class Birdy
{
//variables
int numberOfBeaks;
String birdName;
color birdColor;
PVector location;
// constructor, allows you to make new Birds in the rest of the code
// A constructor is part of the class
Birdy (int nob, String bname, color bColor, PVector loc) {
numberOfBeaks = nob;
birdName = bname;
birdColor = bColor;
location = loc;
}
//The bird appears
void showBird()
{
fill(birdColor);
textSize(24);
text(birdName, location.x, location.y);
ellipse(location.x, location.y, 20, 20);
}
}
void setup() {
size(640, 480);
//fill the array Of Birds with new Birds
arrayOfBirds = new Birdy[numberOfBirds];
//to make 10 birds and put them in the array
for (int i = 0; i < numberOfBirds; i++)
{
// each new bird needs its own set of parameters but will do this when i figure out how to work with this one first!
arrayOfBirds[i]= new Birdy(2, "Tweety "+i, color(255-(i*25), i*25, 255), new PVector(i*40, i*40));
}
}
void draw(int x, int y) {
if (video.available()) {
video.read();
image(video, 0, 0, width, height); // Draw the webcam video onto the screen
int colorX = 0; // X-coordinate of the closest in color video pixel
int colorY = 0; // Y-coordinate of the closest in color video pixel
float closestColor = 500; //we set this to be abritrarily large, once program runs, the first pixel it scans will be set to this value
// Search for the closest in color pixel: For each row of pixels in the video image and
// for each pixel in the yth row, compute each pixel's index in the video
background(0);
//show that first bird we called Tweety by calling the showBird() function on Tweety
Tweety.showBird();
//show all the birds in the array by calling the showBird() method on each object in the array
for(int i = 0; i < arrayOfBirds.length; i++){
arrayOfBirds[i].location = new PVector(x,y);
arrayOfBirds[i].showBird();
}
}
setup();
Gif loopingGif;
Capture video;
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480 // Uses the default video input ---- but i dont think it works
video = new Capture(this, width, height, 30);
video.start();
noStroke();
smooth();
frameRate(10);
loopingGif = new Gif(this, "circle.gif");
String [] animas = {};
video.loadPixels();
int index = 0;
for (int y = 0; y < video.height; y++) {
for (int x = 0; x < video.width; x++) {
// Get the color stored in the pixel
color pixelValue = video.pixels[index];
// Determine the color of the pixel
float colorProximity = abs(red(pixelValue)-27)+abs(green(pixelValue)-162)+abs(blue(pixelValue)-181); //select pixel
// If that value is closer in color value than any previous, then store the
// color proximity of that pixel, as well as its (x,y) location
if (colorProximity < closestColor) {
closestColor = colorProximity;
closestColor=closestColor-10; //Once it "locks" on to an object of color, it wont let go unless something a good bit better (closer in color) comes along
colorY = y;
colorX = x;
}
index++;
}
draw(x,y);
}
image (loopingGif, colorX, colorY);
loopingGif.play();
}here
You need to declare your variable by giving it a type:
Movie video = new Movie();
You've got some other weird things going on here. Why are you specifically calling the setup() function? Processing does that for you automatically. You've also got a bunch of code outside of a function at the bottom of your sketch. Maybe you meant to put that code inside the setup() function?
If you're still getting errors, edit your question to include their exact full text.

Categories

Resources