There is a way to convert view's float coordinates to length in meters or another real unit?
I have a surfaceview that displays the motion of some real body and I want to display the scale of the animation, so I have to get the conversion from coordinates or sizes of the view to meters...
may be in millimeters?
int width= view.getMeasuredWidth(); // will be in px
float mm = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, width, getResources().getDisplayMetrics());
also check out other TypedValue.COMPLEX_UNIT_ (maybe inches?)
Related
TextureView.getBitmap can only be used with width and height parameters, does anyone know if it is possible to get a Bitmap that is taken from the TextureView with a certain X and Y offset?
I'm hoping someone can help me out. I'm making an image manipulation app, and I found I needed a better way to load in large images.
My plan, is to iterate through "hypothetical" pixels of an image (a "for loop" that covers width/height of the base image, so each iteration represents a pixel), scale/translate/rotate that pixels position relative to the view, then use this information to determine which pixels are being displayed in the view itself, then use a combination of BitmapRegionDecoder and BitmapFactory.Options to load in only the section of image that the output actually needs rather than a full (even if scaled) image.
So far I seem to have covered scale of the image and translation properly, but I can't seem to figure out how to calculate rotation. Since it's not a real Bitmap pixel I can't use Matrix.rotate =( Here is the image translations in the onDraw of the view, imgPosX and imgPosY hold the center point of the image:
m.setTranslate(-userImage.getWidth() / 2.0f, -userImage.getHeight() / 2.0f);
m.postScale(curScale, curScale);
m.postRotate(angle);
m.postTranslate(imgPosX, imgPosY);
mCanvas.drawBitmap(userImage.get(), m, paint);
and here is the math so far of how I'm trying to determine if an images pixel is on the screen:
for(int j = 0;j < imageHeight;j++) {
for(int i = 0;i < imageWidth;i++) {
//image starts completely center in view, assume image is original size for simplicity
//this is the original starting position for each pixel
int x = Math.round(((float) viewSizeWidth / 2.0f) - ((float) newImageWidth / 2.0f) + i);
int y = Math.round(((float) viewSizeHeight / 2.0f) - ((float) newImageHeight / 2.0f) + j);
//first we scale the pixel here, easy operation
x = Math.round(x * imageScale);
y = Math.round(y * imageScale);
//now we translate, we do this by determining how many pixels
//our images x/y coordinates have differed from it's original
//starting point, imgPosX and imgPosY in the view start in center
//of view
x = x + Math.round((imgPosX - ((float) viewSizeWidth / 2.0f)));
y = y + Math.round((imgPosY - ((float) viewSizeHeight / 2.0f)));
//TODO need rotation here
}
}
so, assuming my math up until rotation is correct (probably not but it appears to be working so far), how would I then calculate the rotation from that pixels position? I've tried other similar questions like:
Link 1
Link 2
Link 3
without using rotation the pixels I expect to actually be on the screen are represented (I made text file that outputs the results in 1's and 0's so I can have a visual representation of whats on the screen), but with the formula found in those questions the information isn't what is expected. (Scenario: I've rotated an image so only the top left corner is visible in the view. Using the info from Here to rotate the pixel, I should expect to see a triangular set of 1's in the upper left corner of the output file, but that's not the case)
So, how would I calculate a a pixels position after rotation without using the Android matrix? But still get the same results.
And if I've just messed it up entirely my apologies =( Any help would be appreciated, this project has gone on for so long and I want to finally be done lol
If you need any more information I will provide as much as I possibly can =) Thank you for your time
I realize this question is particularly difficult so I will be posting a bounty as soon as SO allows.
You do not need to create your own Matrix, use the existing one.
http://developer.android.com/reference/android/graphics/Matrix.html
You can map bitmap coordinates to screen coordinates by using
float[] coords = {x, y};
m.mapPoints(coords);
float sx = coords[0];
float sy = coords[1];
If you want to map screen to bitmap coordinates, you can create the inverse matrix
Matrix inverse = new Matrix(m);
inverse.inverse();
inverse.mapPoints(...)
I think your overall approach is going to be slow, as doing the pixel manipulation on the CU from Java has a lot of overhead. When drawing bitmaps normally, the pixel manipulation is done on the GPU.
I am trying to build a game and was wondering how would one go about supporting different resolution and screen sizes. For position of sprite I've implemented a basic function which sets the position according to a certain ratio, which I get by getting the screen width and height from sharedDirector's winSize method.
But this approach is not tested as I have yet to develop something to calculate the scaling factor for sprites depending upon the resolution of device. Can somebody advise me some method and tips by which I can correctly calculate the scaling of sprite and suggest a system to avoid the pixelation of sprites if I do apply any such method.
I searched on Google and found that Cocos2d-x supports different resolutions and sizes but I am bound to use Cocos2d only.
EDIT: I am bit confused as this is my first game. Please point out any mistakes that I may have made.
Okay I finally did this by getting the device display denitiy like
getResources().getResources().getDisplayMetrics().densityDpi
and based on it I am multiplying by PTM ratio by 0.75,1,1.5,2.0 for ldpi,mdpi,hdpi,and xhdpi respectively.
I am also changing the scale of sprites accordingly. And for positioning I've kept 320X480 as my base and then multiplying that with a ratio of my current x and y in pixels with my base pixels.
EDIT: Adding some code for better understanding:
public class MainLayer extends CCLayer()
{
CGsize size; //this is where we hold the size of current display
float scaleX,scaleY;//these are the ratios that we need to compute
public MainLayer()
{
size = CCDirector.sharedDirector().winSize();
scaleX = size.width/480f;//assuming that all my assets are available for a 320X480(landscape) resolution;
scaleY = size.height/320f;
CCSprite somesprite = CCSprite.sprite("some.png");
//if you want to set scale without maintaining the aspect ratio of Sprite
somesprite.setScaleX(scaleX);
somesprite.setScaleY(scaleY);
//to set position that is same for every resolution
somesprite.setPosition(80f*scaleX,250f*scaleY);//these positions are according to 320X480 resolution.
//if you want to maintain the aspect ratio Sprite then instead up above scale like this
somesprite.setScale(aspect_Scale(somesprite,scaleX,scaleY));
}
public float aspect_Scale(CCSprite sprite, float scaleX , float scaleY)
{
float sourcewidth = sprite.getContentSize().width;
float sourceheight = sprite.getContentSize().height;
float targetwidth = sourcewidth*scaleX;
float targetheight = sourceheight*scaleY;
float scalex = (float)targetwidth/sourcewidth;
float scaley = (float)targetheight/sourceheight;
return Math.min(scalex,scaley);
}
}
I am trying to build a game and was wondering how would one go about supporting different resolution and screen sizes. For position of sprite I've implemented a basic function which sets the position according to a certain ratio, which I get by getting the screen width and height from sharedDirector's winSize method.
But this approach is not tested as I have yet to develop something to calculate the scaling factor for sprites depending upon the resolution of device. Can somebody advise me some method and tips by which I can correctly calculate the scaling of sprite and suggest a system to avoid the pixelation of sprites if I do apply any such method.
I searched on Google and found that Cocos2d-x supports different resolutions and sizes but I am bound to use Cocos2d only.
EDIT: I am bit confused as this is my first game. Please point out any mistakes that I may have made.
Okay I finally did this by getting the device display denitiy like
getResources().getResources().getDisplayMetrics().densityDpi
and based on it I am multiplying by PTM ratio by 0.75,1,1.5,2.0 for ldpi,mdpi,hdpi,and xhdpi respectively.
I am also changing the scale of sprites accordingly. And for positioning I've kept 320X480 as my base and then multiplying that with a ratio of my current x and y in pixels with my base pixels.
EDIT: Adding some code for better understanding:
public class MainLayer extends CCLayer()
{
CGsize size; //this is where we hold the size of current display
float scaleX,scaleY;//these are the ratios that we need to compute
public MainLayer()
{
size = CCDirector.sharedDirector().winSize();
scaleX = size.width/480f;//assuming that all my assets are available for a 320X480(landscape) resolution;
scaleY = size.height/320f;
CCSprite somesprite = CCSprite.sprite("some.png");
//if you want to set scale without maintaining the aspect ratio of Sprite
somesprite.setScaleX(scaleX);
somesprite.setScaleY(scaleY);
//to set position that is same for every resolution
somesprite.setPosition(80f*scaleX,250f*scaleY);//these positions are according to 320X480 resolution.
//if you want to maintain the aspect ratio Sprite then instead up above scale like this
somesprite.setScale(aspect_Scale(somesprite,scaleX,scaleY));
}
public float aspect_Scale(CCSprite sprite, float scaleX , float scaleY)
{
float sourcewidth = sprite.getContentSize().width;
float sourceheight = sprite.getContentSize().height;
float targetwidth = sourcewidth*scaleX;
float targetheight = sourceheight*scaleY;
float scalex = (float)targetwidth/sourcewidth;
float scaley = (float)targetheight/sourceheight;
return Math.min(scalex,scaley);
}
}
I want to know if there is any way to modify text height and width separately when drawing with canvas. To set text size you can simply do paint.setTextSize(x);but it change text size in X and Y and I need to change text size in X and Y separately as you do with paint.setTextScaleX(x);but there isn't anything like paint.setTextScaleY(y);.
Is any way to implement this or does it already exists in Android ?
Thank you
There is no setTextScaleY method, because there is no need for one. setTextSize multiplies both X and Y scale factors, and setTextScaleX multiplies the X scale factor only. So you could reach any desired scaling scaleX, scaleY this way:
setTextSize(scaleY);
setTextScaleX(scaleX/scaleY); //setTextScaleX scales according to the CURRENT size (setTextScaleX(1) does nothing).