亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android編程實(shí)現(xiàn)支持拖動(dòng)改變位置的圖片中疊加文字功能示例

 更新時(shí)間:2017年01月21日 10:23:07   作者:books1958  
這篇文章主要介紹了Android編程實(shí)現(xiàn)支持拖動(dòng)改變位置的圖片中疊加文字功能,可實(shí)現(xiàn)Android圖片與文字動(dòng)態(tài)操作功能,涉及視圖及圖片動(dòng)態(tài)運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下

本文實(shí)例講述了Android編程實(shí)現(xiàn)支持拖動(dòng)改變位置的圖片中疊加文字功能。分享給大家供大家參考,具體如下:

之所以做了這么一個(gè)Demo,是因?yàn)樽罱?xiàng)目中有一個(gè)奇葩的需求:用戶(hù)拍攝照片后,分享到微信的同時(shí)添加備注,想獲取用戶(hù)在微信的彈出框輸入的內(nèi)容,保存在自己的服務(wù)器上。而事實(shí)上,這個(gè)內(nèi)容程序是無(wú)法獲取的,因此采取了一個(gè)折衷方案,將文字直接寫(xiě)在圖片上。

首先上Demo效果圖:

功能:

1.用戶(hù)自由輸入內(nèi)容,可手動(dòng)換行,并且行滿(mǎn)也會(huì)自動(dòng)換行。
2.可拖動(dòng)改變圖片中文本位置(文字不會(huì)超出圖片區(qū)域)。
3.點(diǎn)擊“生成圖片”按鈕之后,生成一張帶有文字的圖片文件。

代碼不多,直接全部貼上了:

Activity:

/**
 * 將文字寫(xiě)在圖片中(截圖方式),支持拖動(dòng)文字。<br/>
 * 說(shuō)明:很明顯,截圖方式會(huì)降低圖片的質(zhì)量。如果需要保持圖片質(zhì)量可以使用canvas的方式,將文字直接繪制在圖片之上(不過(guò),使用此方式要實(shí)現(xiàn)文字拖動(dòng)較為復(fù)雜)。
 */
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();
        //設(shè)置文本大小
        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());
    //移動(dòng)
    tvInImage.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
        gestureDetector.onTouchEvent(event);
        return true;
      }
    });
  }
  //確認(rèn),生成圖片
  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顯示的內(nèi)容(類(lèi)似于截圖)
  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方向移動(dòng)量
  private float mDx, mDy;
  //移動(dòng)
  private class SimpleGestureListenerImpl extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
      //向右移動(dòng)時(shí),distanceX為負(fù);向左移動(dòng)時(shí),distanceX為正
      //向下移動(dòng)時(shí),distanceY為負(fù);向上移動(dòng)時(shí),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;
    }
  }
  //計(jì)算正確的顯示位置(不能超出邊界)
  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);
  }
}

一個(gè)工具類(lèi):

public class Utility {
  //計(jì)算 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;
  }
}

布局文件:

<?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">
  <RelativeLayout
    android:id="@+id/writeText_img_rl"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal">
    <ImageView
      android:id="@+id/writeText_img"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:maxHeight="360dp"
      android:adjustViewBounds="true"
      android:contentDescription="@null"/>
    <TextView
      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" />
  </RelativeLayout>
  <EditText
    android:id="@+id/writeText_et"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp"
    android:hint="添加備注" />
  <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="confirm"
    android:text="生成圖片" />
</LinearLayout>

更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Android圖形與圖像處理技巧總結(jié)》、《Android開(kāi)發(fā)入門(mén)與進(jìn)階教程》、《Android調(diào)試技巧與常見(jiàn)問(wèn)題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)

希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。

相關(guān)文章

最新評(píng)論