Welcome

首页 / 移动开发 / Android / Android编程实现支持拖动改变位置的图片中叠加文字功能示例

本文实例讲述了Android编程实现支持拖动改变位置的图片中叠加文字功能。分享给大家供大家参考,具体如下:
之所以做了这么一个Demo,是因为最近项目中有一个奇葩的需求:用户拍摄照片后,分享到微信的同时添加备注,想获取用户在微信的弹出框输入的内容,保存在自己的服务器上。而事实上,这个内容程序是无法获取的,因此采取了一个折衷方案,将文字直接写在图片上。
首先上Demo效果图:

功能:
1.用户自由输入内容,可手动换行,并且行满也会自动换行。
2.可拖动改变图片中文本位置(文字不会超出图片区域)。
3.点击“生成图片”按钮之后,生成一张带有文字的图片文件。
代码不多,直接全部贴上了:
Activity:
/** * 将文字写在图片中(截图方式),支持拖动文字。<br/> * 说明:很明显,截图方式会降低图片的质量。如果需要保持图片质量可以使用canvas的方式,将文字直接绘制在图片之上(不过,使用此方式要实现文字拖动较为复杂)。 */public class MainActivity extends AppCompatActivity {//图片组件private ImageView imageView;//位于图片中的文本组件private TextView tvInImage;//图片和文本的父组件private View containerView;//父组件的尺寸private float imageWidth, imageHeight, imagePositionX, imagePositionY;@Overrideprotected 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() {@Overridepublic 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() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic 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);}}@Overridepublic void afterTextChanged(Editable s) {}});final GestureDetector gestureDetector = new GestureDetector(this, new SimpleGestureListenerImpl());//移动tvInImage.setOnTouchListener(new View.OnTouchListener() {@Overridepublic 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 {@Overridepublic 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;}//获取压缩后的bitmapprivate 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 imagefinal 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;}}
布局文件:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="10dp"><RelativeLayoutandroid:id="@+id/writeText_img_rl"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"><ImageViewandroid:id="@+id/writeText_img"android:layout_width="wrap_content"android:layout_height="wrap_content"android:maxHeight="360dp"android:adjustViewBounds="true"android:contentDescription="@null"/><TextViewandroid: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" /></RelativeLayout><EditTextandroid:id="@+id/writeText_et"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="8dp"android:hint="添加备注" /><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="confirm"android:text="生成图片" /></LinearLayout>
更多关于Android相关内容感兴趣的读者可查看本站专题:《Android图形与图像处理技巧总结》、《Android开发入门与进阶教程》、《Android调试技巧与常见问题解决方法汇总》、《Android基本组件用法总结》、《Android视图View技巧总结》、《Android布局layout技巧总结》及《Android控件用法总结》
希望本文所述对大家Android程序设计有所帮助。