android 获取图片上某一个文字位置_Android编程实现支持拖动改变位置的图片中叠加文字功能示例...

本文实例讲述了Android编程实现支持拖动改变位置的图片中叠加文字功能。分享给大家供大家参考,具体如下:

之所以做了这么一个Demo,是因为最近项目中有一个奇葩的需求:用户拍摄照片后,分享到微信的同时添加备注,想获取用户在微信的弹出框输入的内容,保存在自己的服务器上。而事实上,这个内容程序是无法获取的,因此采取了一个折衷方案,将文字直接写在图片上。

首先上Demo效果图:

d15702f1e6008c15a457370c19a5fe56.png

功能:

1.用户自由输入内容,可手动换行,并且行满也会自动换行。

2.可拖动改变图片中文本位置(文字不会超出图片区域)。

3.点击“生成图片”按钮之后,生成一张带有文字的图片文件。

代码不多,直接全部贴上了:

Activity:

/**

* 将文字写在图片中(截图方式),支持拖动文字。

* 说明:很明显,截图方式会降低图片的质量。如果需要保持图片质量可以使用canvas的方式,将文字直接绘制在图片之上(不过,使用此方式要实现文字拖动较为复杂)。

*/

public class MainActivity extends AppCompatActivity {

//图片组件

private ImageView imageView;

//位于图片中的文本组件

private TextView tvInImage;

//图片和文本的父组件

private View containerView;

//父组件的尺寸

private float imageWidth, imageHeight, imagePositionX, imagePositionY;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.image_with_text);

imageView = (ImageView) findViewById(R.id.writeText_img);

EditText editText = (EditText) findViewById(R.id.writeText_et);

tvInImage = (TextView) findViewById(R.id.writeText_image_tv);

containerView = findViewById(R.id.writeText_img_rl);

imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

imageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);

imagePositionX = imageView.getX();

imagePositionY = imageView.getY();

imageWidth = imageView.getWidth();

imageHeight = imageView.getHeight();

//设置文本大小

tvInImage.setMaxWidth((int) imageWidth);

}

});

imageView.setImageBitmap(getScaledBitmap(R.mipmap.test_img));

//输入框

editText.addTextChangedListener(new TextWatcher() {

@Override

public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override

public void onTextChanged(CharSequence s, int start, int before, int count) {

if (s.toString().equals("")) {

tvInImage.setVisibility(View.INVISIBLE);

} else {

tvInImage.setVisibility(View.VISIBLE);

tvInImage.setText(s);

}

}

@Override

public void afterTextChanged(Editable s) {

}

});

final GestureDetector gestureDetector = new GestureDetector(this, new SimpleGestureListenerImpl());

//移动

tvInImage.setOnTouchListener(new View.OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

gestureDetector.onTouchEvent(event);

return true;

}

});

}

//确认,生成图片

public void confirm(View view) {

Bitmap bm = loadBitmapFromView(containerView);

String filePath = Environment.getExternalStorageDirectory() + File.separator + "image_with_text.jpg";

try {

bm.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(filePath));

Toast.makeText(this, "图片已保存至:SD卡根目录/image_with_text.jpg", Toast.LENGTH_LONG).show();

} catch (FileNotFoundException e) {

e.printStackTrace();

}

}

//以图片形式获取View显示的内容(类似于截图)

public static Bitmap loadBitmapFromView(View view) {

Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(bitmap);

view.draw(canvas);

return bitmap;

}

private int count = 0;

//tvInImage的x方向和y方向移动量

private float mDx, mDy;

//移动

private class SimpleGestureListenerImpl extends GestureDetector.SimpleOnGestureListener {

@Override

public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

//向右移动时,distanceX为负;向左移动时,distanceX为正

//向下移动时,distanceY为负;向上移动时,distanceY为正

count++;

mDx -= distanceX;

mDy -= distanceY;

//边界检查

mDx = calPosition(imagePositionX - tvInImage.getX(), imagePositionX + imageWidth - (tvInImage.getX() + tvInImage.getWidth()), mDx);

mDy = calPosition(imagePositionY - tvInImage.getY(), imagePositionY + imageHeight - (tvInImage.getY() + tvInImage.getHeight()), mDy);

//控制刷新频率

if (count % 5 == 0) {

tvInImage.setX(tvInImage.getX() + mDx);

tvInImage.setY(tvInImage.getY() + mDy);

}

return true;

}

}

//计算正确的显示位置(不能超出边界)

private float calPosition(float min, float max, float current) {

if (current < min) {

return min;

}

if (current > max) {

return max;

}

return current;

}

//获取压缩后的bitmap

private Bitmap getScaledBitmap(int resId) {

BitmapFactory.Options opt = new BitmapFactory.Options();

opt.inJustDecodeBounds = true;

BitmapFactory.decodeResource(getResources(), resId, opt);

opt.inSampleSize = Utility.calculateInSampleSize(opt, 600, 800);

opt.inJustDecodeBounds = false;

return BitmapFactory.decodeResource(getResources(), resId, opt);

}

}

一个工具类:

public class Utility {

//计算 inSampleSize 值,压缩图片

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {

// Raw height and width of image

final int height = options.outHeight;

final int width = options.outWidth;

int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {

final int halfHeight = height / 2;

final int halfWidth = width / 2;

// Calculate the largest inSampleSize value that is a power of 2 and keeps both

// height and width larger than the requested height and width.

while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {

inSampleSize *= 2;

}

}

return inSampleSize;

}

}

布局文件:

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:padding="10dp">

android:id="@+id/writeText_img_rl"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal">

android:id="@+id/writeText_img"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:maxHeight="360dp"

android:adjustViewBounds="true"

android:contentDescription="@null"/>

android:id="@+id/writeText_image_tv"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:visibility="invisible"

android:layout_centerInParent="true"

android:background="#79652a"

android:clickable="true"

android:padding="4dp"

android:textColor="@android:color/white"

android:textSize="15sp" />

android:id="@+id/writeText_et"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_marginTop="8dp"

android:hint="添加备注" />

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:onClick="confirm"

android:text="生成图片" />

希望本文所述对大家Android程序设计有所帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值