画面いっぱいのImageViewがある場合。
ImageViewの背景が緑色に設定されています。
ビットマップの比率を維持しながら、ImageViewにビットマップを配置します。
このレイアウトのポートレート写真は、左側と右側の両方に緑色で表示されます
(電話の向き=ポートレート)。
ここで、グリーンが終了してビットマップが開始したときに、エッジの左側のx/y位置を取得する方法を教えてください。
この取り組みプロジェクトの背景は、画像にテキストを書き込んで、テキストを含む新しい画像に画像を保存することです。問題は..
私は画像をSampleSize = 4でスケーリングしているので、 ImageViewはさらに縮小し、この新しい画像を保存すると、約250x350の小さな画像になります。
私が欲しいのは、x/y位置を使用して、書き込まれたテキストを元のinSampleSize = 4画像またはsdcard 1500x3000画像に転送することです
私は自分自身で「数学の計算を行う」必要があるという他の質問を知って読んでいます。この小さな答えが必要です。
明確にするためにスクリーンショットを撮ることができないのを忘れました。
これは次のようになります(「ペン」ボタンを押すと新しいペンが表示されます。各ペンは画面上で独自のテキストと位置を保持しています。
これがimageviewです
import Java.util.HashMap;
import Java.util.UUID;
import Android.app.Activity;
import Android.content.Context;
import Android.graphics.Bitmap;
import Android.graphics.BitmapFactory;
import Android.graphics.Canvas;
import Android.graphics.Color;
import Android.graphics.Paint;
import Android.graphics.Point;
import Android.graphics.Rect;
import Android.graphics.Typeface;
import Android.graphics.drawable.BitmapDrawable;
import Android.graphics.drawable.Drawable;
import Android.os.Environment;
import Android.util.AttributeSet;
import Android.view.Display;
import Android.view.MotionEvent;
import Android.widget.EditText;
import Android.widget.ImageView;
public class DrawView2 extends ImageView {
private HashMap<String, ColorBall2> HashBall ;
private String balID = ""; // variable to know what ball is being dragged
public final String PTPPSERVICE_DERECTORY = "/PTPPservice/";
private Bitmap bitmap;
private EditText ed;
private Paint paint = new Paint();
private Paint paint2 = new Paint();
private Paint pTouch = new Paint();
private EditText addtext;
private Context ctx;
private String imagePath;
private boolean removeBall = false;
int viewWidth = 0;
int viewHeight = 0;
double bitmapHight =0;
double bitmapWidth =0;
double ratio =0;
double startX = 0;
double endX= 0;
double startY= 0;
double endY = 0;
public DrawView2(Context context, AttributeSet atts,String image1) {
super(context, atts);
this.ctx = context;
this.imagePath = image1;
setFocusable(true);
Paint.setStyle(Paint.Style.FILL_AND_STROKE);
Paint.setColor(Color.BLACK);
Paint.setTypeface(Typeface.DEFAULT_BOLD);
Paint2.setStyle(Paint.Style.FILL_AND_STROKE);
Paint2.setColor(Color.RED);
addtext = (EditText) ((Activity) ctx).findViewById(R.id.edittextaddtext);
String filePath = Environment.getExternalStorageDirectory().toString() + imagePath;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
bitmap = BitmapFactory.decodeFile(filePath,options);
// SAVE RATIO
int x = bitmap.getWidth();
int y = bitmap.getHeight();
if(y>x)
ratio = ((double)y)/x;
if(x>y)
ratio = ((double)x)/y;
if(y==x)
ratio = 1;
Drawable bit = new BitmapDrawable(bitmap);
setImageDrawable(bit);
}
public double getRatio() {
return ratio;
}
public HashMap<String, ColorBall2> getHashBall() {
return HashBall;
}
// RETURN THE ON SCREEN RESIZED BITMAP
public double getOnScreenBitmapHight(){
return bitmapHight;
}
public double getOnScreenBitmapWidth(){
return bitmapWidth;
}
// BITMAP SIZE
public int getBitmapHight(){
return bitmap.getHeight();
}
public int getBitmapWidth(){
return bitmap.getWidth();
}
// GET IMAGEVIEW HIGHT WIDTH
public int getViewWidth() {
return viewWidth;
}
public int getViewHeight() {
return viewHeight;
}
// START END X Y
public double getStartX() {
return startX;
}
public double getEndX() {
return endX;
}
public double getStartY() {
return startY;
}
public double getEndY() {
return endY;
}
// SET BALL TEXT
public void addTextToBall(String text) {
if(balID != "")
HashBall.get(balID).setText(text);
}
// PATH
public String getImagePath() {
return imagePath;
}
// THE ORIGINAL INSAMPELSIZE=4 BITMAP
public Bitmap getBitmap() {
return bitmap;
}
// STOP DRAWAING THE BALL
public void removeBall(boolean value) {
removeBall = value;
}
// THE RECT THAT RETURN WRONG VALUE
public Rect getRect(){
Rect r = getDrawable().copyBounds();
int drawLeft = r.left;
int drawTop = r.top;
int drawRight = r.right;
int drawBottom = r.bottom;
return r;
}
@Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){
super.onSizeChanged(xNew, yNew, xOld, yOld);
viewWidth = xNew;
viewHeight = yNew;
}
public void addBall(){
// HERE I TRY TO CALCULATE THE BOUNDS LEFT,RIGHT,TOP AND BOTTOM Edge OF THE BITMAP
//NOT GOING THAT GOOD
if(HashBall == null)
HashBall = new HashMap<String,ColorBall2>();
//X
double drawAbleWidth = viewWidth/ratio;
startX = (viewWidth-drawAbleWidth)/2;
double drawAbleHight = viewHeight/ratio;
startY = drawAbleHight/2;
int ballY = (viewHeight/2);
int ballX = (viewWidth/2);
Point point1 = new Point();
point1.x = (int) ballX;
point1.y = (int) ballY;
String uuId = UUID.randomUUID().toString();
HashBall.put(uuId,(new ColorBall2(ctx,R.drawable.pen1, point1,uuId)));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//canvas.drawCircle(10,10,10,null);
if(!removeBall && HashBall != null){
for (String key : HashBall.keySet()) {
//System.out.println("Key: " + key + ", Value: " + map.get(key));
if(addtext!=null)
//canvas.drawCircle(HashBall.get(key).getX(), HashBall.get(key).getY(), 10, Paint2);
canvas.drawBitmap(HashBall.get(key).getBitmap(), HashBall.get(key).getX()-10, HashBall.get(key).getY()-80, null);
canvas.drawText (HashBall.get(key).getText() + " X="+HashBall.get(key).getX() + " Y="+HashBall.get(key).getY()
, HashBall.get(key).getX(), HashBall.get(key).getY(), Paint);
}
}
}
// events when touching the screen
@Override
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
int X = (int)event.getX();
int Y = (int)event.getY();
switch (eventaction )
{
case MotionEvent.ACTION_DOWN: // touch down so check if the finger is on a ball
balID = "";
for (String key : HashBall.keySet()) {
// check if inside the bounds of the ball (circle)
// get the center for the ball
int centerX = HashBall.get(key).getX() + 15;
int centerY = HashBall.get(key).getY() + 15;
// calculate the radius from the touch to the center of the ball
double radCircle = Math.sqrt( (((centerX-X)*(centerX-X)) + (centerY-Y)*(centerY-Y)));
// if the radius is smaller then 23 (radius of a ball is 22), then it must be on the ball
if (radCircle < 33){
balID = HashBall.get(key).getID();
addtext.setText(HashBall.get(key).getText());
break;
}
}
break;
case MotionEvent.ACTION_MOVE: // touch drag with the ball
// move the balls the same as the finger
if (balID != "") {
HashBall.get(balID).setX(X-25);
HashBall.get(balID).setY(Y-25);
}
break;
case MotionEvent.ACTION_UP:
// touch drop - just do things here after dropping
break;
}
// redraw the canvas
invalidate();
return true;
}
}
比率がわかっている場合は、画像の横に配置されるマージンの幅を導き出すことができます。
// These holds the ratios for the ImageView and the bitmap
double bitmapRatio = ((double)bitmap.getWidth())/bitmap.getHeight()
double imageViewRatio = ((double)imageView.getWidth())/imageView.getHeight()
これで、bitmapRatioがimageViewRatioより大きい場合、ビットマップの高さが等しい場合、ビットマップがimageviewよりも広いことを意味します。つまり、上部と下部に空白があります。
逆に、bitmapRatioがimageViewRatioよりも小さい場合は、左右に空白ができます。これから、0になるので、かなり簡単に座標の1つを取得できます。
if(bitmapRatio > imageViewRatio)
{
drawLeft = 0;
}
else
{
drawTop = 0;
}
他の座標を取得するには、左と右にスペースがある2番目のケースを考えてください。ここでは、ビットマップとimageViewの高さが等しいため、幅間の比率は比率間の比率に等しくなります。 imageViewの幅がわかっているので、これを使用してビットマップの幅を把握できます。同様に、幅が等しい場合は高さを計算できます。ただし、幅は比率に反比例するため、比率間の比率の逆数を使用する必要があります。
if(bitmapRatio > imageViewRatio)
{
drawLeft = 0;
drawHeight = (imageViewRatio/bitmapRatio) * imageView.getHeight();
}
else
{
drawTop = 0;
drawWidth = (bitmapRatio/imageViewRatio) * imageView.getWidth();
}
ビットマップの幅または高さを取得したら、横のスペースを取得するのは簡単です。これは、ビットマップとimageViewの幅または高さの違いの半分です。
if(bitmapRatio > imageViewRatio)
{
drawLeft = 0;
drawHeight = (imageViewRatio/bitmapRatio) * imageView.getHeight();
drawTop = (imageView.getHeight() - drawHeight)/2;
}
else
{
drawTop = 0;
drawWidth = (bitmapRatio/imageViewRatio) * imageView.getWidth();
drawLeft = (imageView.getWidth() - drawWidth)/2;
}
これは私が共有したかったメソッドです、それはgetImageMatrixを使用してimageView内のビットマップのオフセットを返します
public static int[] getBitmapOffset(ImageView img, Boolean includeLayout) {
int[] offset = new int[2];
float[] values = new float[9];
Matrix m = img.getImageMatrix();
m.getValues(values);
offset[0] = (int) values[5];
offset[1] = (int) values[2];
if (includeLayout) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) img.getLayoutParams();
int paddingTop = (int) (img.getPaddingTop() );
int paddingLeft = (int) (img.getPaddingLeft() );
offset[0] += paddingTop + lp.topMargin;
offset[1] += paddingLeft + lp.leftMargin;
}
return offset;
}
それがあなたが探しているものであれば、内部のドローアブルの(x、y)座標を取得できるはずです。これを試して:
ImageView img = (ImageView)findViewById(R.id.img);
Rect r = img.getDrawable().getBounds();
int drawLeft = r.left;
int drawTop = r.top;
int drawRight = r.right;
int drawBottom = r.bottom;
drawLeft
はXの値です。
drawTop
はY値です。
私自身、多くの問題を抱えていましたが、実際には非常に単純であることがわかりました:)
float points[] = {bitmap.getWidth()/2,bitmap.getHeight()/2}; matrix.mapPoints(points); matrix.postScale(scale, scale, points[0], points[1]);