I created my first JavaFX app that displays images. I want it to zoom the image to full size on mouse down (centered on cursor position) and to refit the image on mouse up.
All is working fine but the i don't know how to center on cursor position. My zoom method looks like that at the moment:
private void zoom100(double cursorx, double cursory){
double centery = imageView.getLayoutBounds().getHeight()/2;
double centerx = imageView.getLayoutBounds().getWidth()/2;
imageView.setFitHeight(-1); //zooms height to 100%
imageView.setFitWidth(-1); //zooms width to 100%
imageView.setTranslateX(centerx-cursorx); //moves x
imageView.setTranslateY(centery-cursory); //moves y
}
My idea is to set an offset with translate. I am not sure if translate is the correct approach. If it is the correct approach how to calculate the correct values? (centerx-cursorx) is wrong!
I uploaded the code here: https://github.com/dermoritz/FastImageViewer (it is working now - see my answer)
I didn't test it but I think the order is wrong. you calculate the center before you set the fit size. By setting the fit size your image view will change it's preferred size. therefore the center point won't match anymore.
I found a solution, but i am still not sure if this is a good way to go:
private void zoom100(double x, double y) {
double oldHeight = imageView.getBoundsInLocal().getHeight();
double oldWidth = imageView.getBoundsInLocal().getWidth();
boolean heightLarger = oldHeight>oldWidth;
imageView.setFitHeight(-1);
imageView.setFitWidth(-1);
//calculate scale factor
double scale=1;
if(heightLarger){
scale = imageView.getBoundsInLocal().getHeight()/oldHeight;
}else {
scale = imageView.getBoundsInLocal().getWidth()/oldWidth;
}
double centery = root.getLayoutBounds().getHeight() / 2;
double centerx = root.getLayoutBounds().getWidth() / 2;
double xOffset = scale * (centerx - x);
double yOffset = scale *(centery - y);
imageView.setTranslateX(xOffset);
imageView.setTranslateY(yOffset);
}
The picture must be centered within "root". I think there should be something more direct - only using properties of imageview?!
Meanwhile the app works using this code: https://github.com/dermoritz/FastImageViewer
Related
I need to switch the height and width without changing the _pointSW value.
These are the variables:
private int _width;
private int _height;
private Point _pointSW;
I am not able to find the changeSides function on the oracle website which is the function they say to use in my assigment so i am not sure if there is some sort of command to do this? any assistance would be great thanks
public void changeSides()
{
}
Assumptions
To increase the height, means stretching the medium upwards.
To increase the width, means stretching the medium rightwards.
Notes
let pos be the southeast point
let width , and height be the two sizes we start width
let corner be the southwest point
Pseudo code
// swapping the width and height can
// be thought of as subtracting away width
// then adding the height value.
corner.x = pos.x + height - width
If any assumptions are incorrect, invalid, or needs changing. Feel free to notify me!
you need a temporary variable for this one.
public void changeSides() {
int temp = width;
int width = height;
int height = temp;
}
I have following pdf with crop box as shown below
Rotated the page to make it horizontal using below code
PDPageContentStream cs = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.PREPEND, false, false);
PDRectangle cropBox = page.getCropBox();
float tx = (cropBox.getLowerLeftX() + cropBox.getUpperRightX()) / 2;
float ty = (cropBox.getLowerLeftY() + cropBox.getUpperRightY()) / 2;
cs.transform(Matrix.getTranslateInstance(tx, ty));
cs.transform(Matrix.getRotateInstance(Math.toRadians(5), 0, 0));
cs.transform(Matrix.getTranslateInstance(-tx, -ty));
cs.close();
The result from above code is
Since coordinates has been changed after affine transformation, for old crop box coordinates i am getting different section. I want to get the original section which i had pointed before rotation.
So,I have tried following techniques to get new coordinates, but didn't get the result
double x_transformed = (x*Math.cos(angle))-(y*Math.sin(angle));
double y_transformed = (x*Math.sin(angle))+(y*Math.cos(angle));
double X_transformed = (X*Math.cos(angle))-(Y*Math.sin(angle));
double Y_transformed = (X*Math.sin(angle))+(Y*Math.cos(angle));
Please suggest me solutions from which i can exactly crop the required section.
The data provided in the question is for reference only.Actual input files can get from below link :
drive.google.com/open?id=0BxPYWA8sfqTDVmY5YVQyZTZwSTA
Thanks in advance.
The issue is that you rotated the page around the center of the original crop box of the page (which defaults to the media box):
PDRectangle cropBox = page.getCropBox();
float tx = (cropBox.getLowerLeftX() + cropBox.getUpperRightX()) / 2;
float ty = (cropBox.getLowerLeftY() + cropBox.getUpperRightY()) / 2;
and thereafter you restrict to your new crop box:
int x = 39;
int y = 450;
int x2 = 360;
int y2= 500;
page.setCropBox(new PDRectangle(new BoundingBox((int)x, (int)y,(int)x2, (int)y2)));
In your previous question your task was to keep the center of the page crop box fixed and rotate everything around it. Thus, there it was correct to calculate the tx and ty from the page crop box.
Your task now, on the other hand, is to keep the center of the box fixed to which you eventually want to crop the page.
Thus, you now have to calculate tx and ty using the corners of that other box:
float tx = (x + x2) / 2;
float ty = (y + y2) / 2;
Alternatively you can simply change the order and first crop the page to the box between (x,y) and (x2,y2) and then rotate around the center of the changed crop box.
Yet another option would be to change the new crop box coordinates by the vector its center has been moved by the rotation.
I am currently developing a remote desktop application in Java, but i am stuck on calculating the screen coordinates for remote mouse clicking.
For example, the remote computer has a resolution of 1024x768, but the panel that renders the image and handles the clicks is only 800x600.How can I calculate the coordinates, so when I press my panel in the upper right corner, it also clicks on the remote computer there?
I tried
x = clickedX / (remoteX/clickedX)
and
x = clickedX * (remoteX/clickedX)
but it never seemed to work.
I appreciate your help.
If I properly understand what you want to do, you are scaling your targets resolution up/down displaying a smaller/bigger image of the remote desktop.
So you need to calculate the transformation with the scale factor you use.
int targetWidth = 1024;
int targetHeight = 768;
int myWidth = 800;
int myHeight = 600;
double scaleX = targetWidth/myWidth;
double scaleY = targetHeight/myHeight;
double targetMouseX = myMouseX * scaleX; //
double targetMouseY = myMouseY * scaleY; //
with targetMouseX & Y as your "output" and myMouseX&Y as your inputs, e.g. your mouse event.
What i am trying to achieve is to draw dot at the exact same location as black dot already present in image , but there are problem that i have to face regarding image:
Image can change its densities in multiple screens(so no fixed size)
Given image can be of any size , i have to convert it to appropriate size to show on custom View.
and How to show image in custom view so its density remain the same ?
Now problems regarding dots drawing:
How can i identify black dots x,y axis dynamically to draw at the same exact black dot drawn in image of custom view.
Is there a good way to achieve question 1 dynamically or i should hard code dots.
What i have done so far:
I have moved all images to drawable folder and done layout_width = wrap_content and height the same as width.
<com.jutt.dotbot.ConnectDotsView
android:id="#+id/gfxImage"
android:layout_width="500dpi"
android:layout_height="600dpi"
android:layout_marginTop="100dip"
android:layout_centerHorizontal="true"/>
I've look hard coded points by Toast the point on each ACTION_DOWN in onTouchEvent and then noted then and given to the class ConnectDotsView .
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
L.s(getContext(), "x = "+x+"y = "+y);
break;
After i've noted all points drawn , i am giving this class back that same points to draw , by calling:
public void setPoints(List<Point> points) {
this.mPoints = points;
}
Now Biggest problem [which i think still persist] , (x,y) on screen 1152w*720h may not be same on 480w*600h , so what i've done is who a function to actually convert those points.
private static final int OLDSCREENX = 1152;
private static final int OLDSCREENY = 720;
private int[] makeDimentionGeneric(float oldScreenX, float oldScreenY,
float oldX, float oldY) {
// get screen size
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
final float y = displaymetrics.heightPixels;
final float x = displaymetrics.widthPixels;
int[] i = new int[] { (int) ((oldX / oldScreenX) * x),
(int) ((oldY / oldScreenY) * y) };
return i;
}
and i am calling this while setting the points like makeDimentionGeneric(OLDSCREENX, OLDSCREENY, p.x, p.y); when p.x and p.y are hardcoded stored value from screen.
Now what happens when i try to run it in different devices.
When am i doing it wrong and how can i achieve it correctly ? please guys i've worked hard studied but can't seems to find a better approach than i've mentioned.
[Update] as requested(21 jul 2015):
private int[] makeDimentionGeneric(float oldScreenX, float oldScreenY,
float oldX, float oldY) {
// convert all px to dp
oldScreenY = convertPixelsToDp(oldScreenY, this);
oldScreenX = convertPixelsToDp(oldScreenX,this);
oldX = convertPixelsToDp(oldX,this);
oldY = convertPixelsToDp(oldY,this);
// get screen size
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
final float y = convertPixelsToDp(displaymetrics.heightPixels, this);
final float x = convertPixelsToDp(displaymetrics.widthPixels, this);
int[] i = new int[] { (int)((oldX / oldScreenX) * x),
(int) ((oldY / oldScreenY) * y) };
return i;
}
Since your image differs depending on DPI your pixel calculations must also differ depending on DPI. Consider the following question:
Converting pixels to dp
In your case (copied from answer in above question) you probably want to use this method:
/**
* This method converts device specific pixels to density independent pixels.
*
* #param px A value in px (pixels) unit. Which we need to convert into db
* #param context Context to get resources and device specific display metrics
* #return A float value to represent dp equivalent to px value
*/
public static float convertPixelsToDp(float px, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float dp = px / (metrics.densityDpi / 160f);
return dp;
}
I'm trying to make a bitmap rotate and point towards the mouse but I get strange results:
Video: http://www.truploader.com/view/993341
The mouse isn't visible it does rotate, however it doesn't rotate to the tip of the mouse point.
Code:
/**
* Rotates the object based on a point
*/
public void setRotation(float x, float y)
{
float XDistance = this.xPos - x;
float YDistance = this.yPos - y;
float Radians = (float) Math.atan2(YDistance, XDistance);
this.degrees = Math.round((Radians*180/Math.PI));
this.moveObject();
this.r.setRotate(this.degrees, this.picture.getWidth() / 2, this.picture.getHeight()); //origin of the base
// this.r.setRotate(this.degrees, this.picture.getWidth() / 2, this.picture.getHeight() / 2);
}
Mouse position is x, and y. Anyone any ideas?
Where do you get the "mouse position"? I guess you take it from a MotionEvent, so notice this coordinates are relative to the target View origin.
What results do you expect? Rotates the object based on a point could mean a lot of things. What is wrong with it?
Are the degrees correct? Initialize your object, fake a mouse position and see if this.degrees is what you expect it to be and what you need it to be. If it doesn't work, consider writing a unit test.
What does this.moveObject(); do? Does it do, what it's supposed to do correctly?
this.r.setRotate( does it need degrees? Why this.picture.getWidth() / 2? About what point does it rotate?
So, what's wrong?