赞
踩
工作日志:其实这是两年前就碰到的需求,之前没有整理,也没有继续优化和实现,这次又用到这样的需求,所以记录下来,既是一种代码记录,也是一种复习bitmap和canvas的好手段,这里提供一种思路,就是将原图的bitmap生成的canvas上绘制图片或者文字。
按照惯例上实现图:
上代码:
- package com.example.testretrifit;
-
- import androidx.appcompat.app.AlertDialog;
- import androidx.appcompat.app.AppCompatActivity;
-
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Rect;
- import android.os.Bundle;
- import android.os.Environment;
- import android.text.Layout;
- import android.text.StaticLayout;
- import android.text.TextPaint;
- import android.util.Log;
- import android.view.View;
- import android.widget.ImageView;
- import android.widget.TextView;
- import android.widget.Toast;
-
- import com.google.gson.Gson;
- import com.trello.rxlifecycle4.RxLifecycle;
- import com.trello.rxlifecycle4.components.support.RxFragmentActivity;
-
- import org.json.JSONObject;
-
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Objects;
- import java.util.concurrent.TimeUnit;
-
- import io.reactivex.android.schedulers.AndroidSchedulers;
- import io.reactivex.disposables.Disposable;
- import io.reactivex.schedulers.Schedulers;
- import okhttp3.MediaType;
- import okhttp3.OkHttpClient;
- import okhttp3.RequestBody;
- import retrofit2.Retrofit;
- import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
-
- public class MainActivity extends AppCompatActivity implements View.OnClickListener {
-
- private TextView tv_text;
- private Service service;
- private ImageView iv_bitmap;
- private ImageView iv_bitmap2;
- private Bitmap bitmap;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
-
- tv_text = findViewById(R.id.tv_text);
-
-
- iv_bitmap = findViewById(R.id.iv_bitmap);
-
- iv_bitmap2 = findViewById(R.id.iv_bitmap2);
-
-
- bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.a);
- // iv_bitmap.setImageBitmap(addTextWatermark(bitmap, 100, Color.WHITE, 0, bitmap.getHeight() / 2, true, "wdnmd,什么情况"));
-
- Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.mipmap.timg);
- iv_bitmap2.setImageBitmap(addTextWatermark(bitmap2, 20, Color.WHITE, 0, bitmap.getHeight() / 2, true, "wdnmd,什么情况"));
-
-
- tv_text.setOnClickListener(this);
- OkHttpClient client = new OkHttpClient()
- .newBuilder()
- .readTimeout(10000, TimeUnit.SECONDS)
- .connectTimeout(10000, TimeUnit.SECONDS)
- .addNetworkInterceptor(new HeaderInpterceptor())
- .build();
- Retrofit retrofit = new Retrofit.Builder()
- .baseUrl("http://192.168.2.156/")
- .addConverterFactory(CommonGsonFactory.create())
- .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
- .client(client)
- .build();
-
- service = retrofit.create(Service.class);
-
- Map<String, Object> map = new HashMap<>();
- map.put("username", "13666666666");
- map.put("password", "zaq1@WSX");
-
- Disposable disposable = service.login(RequestBody.create(MediaType.get("application/json"), new Gson().toJson(map)))
- .subscribeOn(Schedulers.newThread())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(responseBody -> {
-
-
- Configs.token = new JSONObject(responseBody.string()).getString("access_token");
- getUserInfo();
- }, throwable -> Toast.makeText(this, "出错", Toast.LENGTH_SHORT).show()
- );
-
-
-
- /*
- Observable.create(new ObservableOnSubscribe<ResponseBody>() {
- @Override
- public void subscribe(ObservableEmitter<ResponseBody> emitter) throws Exception {
- }
- }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<ResponseBody>() {
- @Override
- public void accept(ResponseBody responseBody) throws Exception {
- }
- }).dispose();
- */
-
- /* Observable.just("hehe").subscribeOn(AndroidSchedulers.mainThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {
- @Override
- public void accept(String s) throws Exception {
- tv_text.setText(s);
- }
- }).dispose();*/
-
-
- }
-
- private void getUserInfo() {
-
- Disposable disposable = service.getInfo(new HashMap<>())
- .subscribeOn(Schedulers.newThread())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(responseBody -> {
-
- tv_text.setText(responseBody.string());
-
- });
-
-
- }
-
- public void downLoadFile() {
- Map<String, Object> map = new HashMap<>();
- map.put("fileUrl", "http://192.168.2.126:80/group1/M00/45/91/wKgCfl8RA9CAS4tZAAAtjJqlrzg697.png");
- Disposable disposable = service.downLoadFile(map)
- .subscribeOn(Schedulers.newThread())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(responseBody -> {
- InputStream is = null;
- byte[] buf = new byte[512];
- int len = 0;
- FileOutputStream fos = null;
-
- //储存下载文件的目录
- File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
- if (!dir.exists()) {
- dir.mkdirs();
- }
- File file = new File(dir, "hehe");
-
- try {
-
- is = responseBody.byteStream();
- Toast.makeText(MainActivity.this, is.available() + "", Toast.LENGTH_SHORT).show();
- long total = is.available();
- fos = new FileOutputStream(file);
- long sum = 0;
- while ((len = is.read(buf)) != -1) {
- fos.write(buf, 0, len);
- sum += len;
- int progress = (int) (sum * 1.0f / total * 100);
- //下载中更新进度条
- // listener.onDownloading(progress);
- tv_text.setText(progress + "");
- }
- fos.flush();
- //下载完成
- // listener.onDownloadSuccess(file);
- } catch (Exception e) {
- // listener.onDownloadFailed(e);
- } finally {
-
- try {
- if (is != null) {
- is.close();
- }
- if (fos != null) {
- fos.close();
- }
- } catch (IOException e) {
-
- }
-
- }
-
- });
- }
-
- @Override
- public void onClick(View view) {
- downLoadFile();
- }
-
-
- /**
- * 给图片添加水印 当需要换行的时候,推荐使用StaticLayout 这种实现方式
- * @param src 原bitmap
- * @param textSize 文字大小
- * @param x 距离图片位图的左边距
- * @param y 距离图片位图的上边距
- * @param recycle 是否回收bitmap,建议true
- * @param text 绘制内容
- * */
- public Bitmap addTextWatermark(Bitmap src, int textSize, int color, float x, float y, boolean recycle, String text) {
- Objects.requireNonNull(src, "src is null");
- Bitmap ret = src.copy(src.getConfig(), true);
- TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
- Canvas canvas = new Canvas(ret);
- paint.setColor(color);
- paint.setTextSize(src.getWidth() / 20);
- Rect bounds = new Rect();
- String content = "时 间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\n" + "内 容:" + text;
- /*
- 单行文字的实现代码
- paint.getTextBounds(content, 0, content.length(), bounds);
- canvas.drawText(content, x, y, paint);*/
-
- canvas.translate(x, y);
- StaticLayout myStaticLayout = new StaticLayout(content, paint, canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
- myStaticLayout.draw(canvas);
-
- // canvas.drawBitmap(bitmap, 0, 0, null);//绘制小图片使用的代码
- if (recycle && !src.isRecycled()) src.recycle();
- return ret;
- }
- }
布局文件:
- <?xml version="1.0" encoding="utf-8"?>
- <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="100dp"
- android:text="Hello World!"
- android:id="@+id/tv_text"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:id="@+id/iv_bitmap2"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- />
-
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/iv_bitmap"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- />
-
-
- </androidx.constraintlayout.widget.ConstraintLayout>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。