• 本来是想做一下ListView生成长图的,最后发现ListView未显示部分获取不到,就把ListView改成了NestedScrollView包裹LinearLayout,在LinearLayout中动态添加条目布局。 先看一下效果图: 布局activity_weather_...

    本来是想做一下ListView生成长图的,最后发现ListView未显示部分获取不到,就把ListView改成了NestedScrollView包裹LinearLayout,在LinearLayout中动态添加条目布局。
    先看一下效果图:
    生成的长图.jpg

    布局activity_weather_future:

    <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/srl"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
                <android.support.v4.widget.NestedScrollView
                    android:id="@+id/nsv"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:fillViewport="true">
    
                    <!--设置paddingBottom是为了在长图下方添加logo图片-->
                    <LinearLayout
                        style="@style/MatchMatch"
                        android:orientation="vertical"
                        android:paddingBottom="@dimen/dp_70">
    
                        <TextView
                            style="@style/MatchWrap"
                            android:layout_marginTop="@dimen/dp_10"
                            android:gravity="center_horizontal"
                            android:tag="skin:future_text_main:textColor"
                            android:text='@{future == null || future.heWeather6.get(0).basic == null?"":future.heWeather6.get(0).basic.location}'
                            android:textColor="@color/future_text_main_default"
                            android:textSize="@dimen/sp_24" />
    
                        <TextView
                            style="@style/MatchWrap"
                            android:layout_marginTop="@dimen/dp_10"
                            android:gravity="center_horizontal"
                            android:tag="skin:future_text_main:textColor"
                            android:text='@{@string/future_update_time+(future == null || future.heWeather6.get(0).update == null?"":future.heWeather6.get(0).update.loc)}'
                            android:textColor="@color/future_text_main_default"
                            android:textSize="@dimen/sp_16" />
    
                        <LinearLayout
                            android:id="@+id/ll"
                            style="@style/MatchWrap"
                            android:orientation="vertical" />
                    </LinearLayout>
                </android.support.v4.widget.NestedScrollView>
    </android.support.v4.widget.SwipeRefreshLayout>

    主要操作的就是这个id为ll的LinearLayout,但也别忘了NestedScrollView,不然不会滚动啊。

    页面代码:
    获取数据源后,循环动态创建条目布局,添加到ll中

    mList.clear();
    mList.addAll(futureWeatherModel.getHeWeather6().get(0).getDaily_forecast());
    ll.removeAllViews();
    for (int i = 0; i < mList.size(); i++) {
           ViewDataBinding dataBinding = DataBindingUtil.inflate(LayoutInflater.from(FutureWeatherActivity.this), R.layout.item_weather_future, null, false);
           dataBinding.setVariable(BR.daily, mList.get(i));
           ll.addView(dataBinding.getRoot());
    }
    srl.setRefreshing(false);

    我这里数据源是根据和风天气免费api获取的七天天气,测试的时候可以自己造几条假数据。

    ll.setOnLongClickListener(v -> {
                //如果还在刷新,长按无效,确保生成长图时,数据已经获取到,动态布局已经添加完毕。
                if (srl.isRefreshing()) {
                    return true;
                }
                Toast.makeText(FutureWeatherActivity.this, "生成长图", Toast.LENGTH_SHORT).show();
                //获取到长图bitmap
                Bitmap listViewBitmap = PhotoUtil.getViewGroupBitmap(nsv);
                //展示长图
                bitmapDialog = DialogUtil.showBitmapDialog(FutureWeatherActivity.this, listViewBitmap, bitmapCallback);
                return true;
            });

    上面就是获取数据、根据数据创建条目添加到ll中、设置ll的长按事件,接下来才是本文的重点,我抽取成了工具方法放在了PhotoUtil中。

        /**
         * 截取viewGroup内容,生成图片
         *
         * @param viewGroup 容器控件
         * @return 图片bitmap
         */
        public static Bitmap getViewGroupBitmap(ViewGroup viewGroup) {
            int h = 0;
            Bitmap bitmap;
            for (int i = 0; i < viewGroup.getChildCount(); i++) {
                h += viewGroup.getChildAt(i).getHeight();
            }
            // 创建相应大小的bitmap
            bitmap = Bitmap.createBitmap(viewGroup.getMeasuredWidth(), h,Bitmap.Config.ARGB_4444);
            final Canvas canvas = new Canvas(bitmap);
            //获取当前主题背景颜色,设置canvas背景
            canvas.drawColor(SkinManager.getInstance().getResourceManager().getColor("future_bg"));
            //画文字水印,不需要的可删去下面这行
            drawTextToBitmap(viewGroup.getContext(), canvas, viewGroup.getMeasuredWidth(), h);
            //绘制viewGroup内容
            viewGroup.draw(canvas);
            //createWaterMaskImage为添加logo的代码,不需要的可直接返回bitmap
            return createWaterMaskImage(bitmap, BitmapFactory.decodeResource(viewGroup.getResources(), R.drawable.icon_mark));
        }

    这里使用SkinManager换肤功能,获取了当前主题背景颜色,可用Color.parseColor(“#8ac5ec”)替代。
    想要使用SkinManager的,可以看一下这篇文章:使用SkinManager实现换肤功能

    到这里,生成长图功能已经实现了,注意一下我使用的Bitmap.Config是ARGB_4444,如果感觉不清晰的话,可改为ARGB_8888,但是图很大的话可能会OOM了,如果对透明度没啥要求可以改为RGB_565,再对图片压缩一下就更好了。
    下面写一下添加文字水印drawTextToBitmap方法,上面的代码顺序不要改变,文字是要加在背景上的。

    /**
         * 给图片添加水印
         *
         * @param context
         * @param canvas  画布
         * @param width   宽
         * @param height  高
         */
        public static void drawTextToBitmap(Context context, Canvas canvas, int width, int height) {
            //要添加的文字
            String logo = "皮卡搜";
            //新建画笔,默认style为实心
            Paint paint = new Paint();
            //设置颜色,颜色可用Color.parseColor("#6b99b9")代替
            paint.setColor(SkinManager.getInstance().getResourceManager().getColor("future_text_bg"));
            //设置透明度
            paint.setAlpha(80);
            //抗锯齿
            paint.setAntiAlias(true);
            //画笔粗细大小
            paint.setTextSize((float) DensityUtil.dip2px(context, 30));
            //保存当前画布状态
            canvas.save();
            //画布旋转-30度
            canvas.rotate(-30);
            //获取要添加文字的宽度
            float textWidth = paint.measureText(logo);
            int index = 0;
            //行循环,从高度为0开始,向下每隔80dp开始绘制文字
            for (int positionY = -DensityUtil.dip2px(context, 30); positionY <= height; positionY += DensityUtil.dip2px(context, 80)) {
                //设置每行文字开始绘制的位置,0.58是根据角度算出tan30°,后面的(index++ % 2) * textWidth是为了展示效果交错绘制
                float fromX = -0.58f * height + (index++ % 2) * textWidth;
                //列循环,从每行的开始位置开始,向右每隔2倍宽度的距离开始绘制(文字间距1倍宽度)
                for (float positionX = fromX; positionX < width; positionX += textWidth * 2) {
                    //绘制文字
                    canvas.drawText(logo, positionX, positionY, paint);
                }
            }
            //恢复画布状态
            canvas.restore();
        }

    上面tan30°的计算方式是由下图得来的
    tan30°.png
    图中A为原canvas,B为旋转-30°后的canvas,width,height为canvas宽高,可以看到旋转后,X坐标向右偏移了,所以绘制时,应向左偏移-tan30°*height,X坐标才能与原坐标相同。

    Y坐标虽然也偏移了,但是如图所示,黑色粗线所示的范围是可能绘制不到的区域,且高宽比越大,绘制不到的区域越小,手机的宽度是不变的,当高宽比大于图中height2与width2的比例后,就能做到全绘制。

    在我测试的项目里基本不会出现黑色粗线区域,所以我这里没有对高度进行处理,如有需要,可在代码外循环positionY <= height增加height即可。

    文字水印加上了,还有个添加logo图标的,一般会要求图上有自己公司的标识嘛。

    /**
         * 添加logo水印
         *
         * @param src    原图片
         * @param logo   logo
         * @return 水印图片
         */
        public static Bitmap createWaterMaskImage(Bitmap src, Bitmap logo) {
            if (src == null) {
                return null;
            }
            //原图宽高
            int w = src.getWidth();
            int h = src.getHeight();
            //logo宽高
            int ww = logo.getWidth();
            int wh = logo.getHeight();
            //创建一个和原图宽高一样的bitmap
            Bitmap newBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444);
            //创建
            Canvas canvas = new Canvas(newBitmap);
            //绘制原始图片
            canvas.drawBitmap(src, 0, 0, null);
            //新建矩阵
            Matrix matrix = new Matrix();
            //对矩阵作缩放处理
            matrix.postScale(0.1f, 0.1f);
            //对矩阵作位置偏移,移动到底部中间的位置
            matrix.postTranslate(0.5f * w - 0.05f * ww, h - 0.1f * wh - 3);
            //将logo绘制到画布上并做矩阵变换
            canvas.drawBitmap(logo, matrix, null);
            // 保存状态
            canvas.save(Canvas.ALL_SAVE_FLAG);// 保存
            // 恢复状态
            canvas.restore();
            return newBitmap;
        }

    这样本文内容就完成了,记得一点我这里是只有七条数据,所以不会OOM,如果你需要超长图的话,一定要进行图片压缩,我测的超过30条就很可能崩掉了。

    虽然实现了生成长图和添加水印,但是我初衷是想在ListView上做的,感觉按照动态添加的思路,还是可以实现的,其实如果列表数据过多的话,做这个意义也不大,而数据不多的话,用这个也已经可以实现了。长图的用途无非跟简书一样是为了作分享,简书是用webView加载的,html页面进行了数据处理,不过也可以尝试一下。先写到这吧,ListView跟WebView试过之后,再来记一下,如果有做过的,也可以留言交流一下。

    展开全文
  • 先上图: 上代码 ------------------------MainActivity------------------------ package ...import android.graphics.Bitmap;...import android.os.Environment;...import android.su...

    先上图:

    上代码

    ------------------------MainActivity------------------------

    package com.example.zhuoshi.watermarkdemo;
    
    import android.graphics.Bitmap;
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.Toast;
    /**
     * Author: baipenggui
     * Date: 2019/1/23 16:06
     * Email: 1528354213@qq.com
     * Description: 在Activity中进行图片展示,以及图片保存
     */
    public class MainActivity extends AppCompatActivity {
        private static String filePath = Environment.getExternalStorageDirectory() + "/WatermarkPicture/";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            String photoAddress = "海淀区-清河路-西三旗桥";
            String phoneDate = "2019-01-22";
            String illicitCode = "1008";
            String illicitBehavior = "闯红灯";
            String equipmentNumber = "fgf54327d";
            String antifakeInformation = "*#4%6&*@";
            ImageView imageView = findViewById(R.id.image);
            int resource = R.drawable.girl;
            WatermarkSettings.getmInstance(this);
            Bitmap bitmap = WatermarkSettings.createWatermark(resource, photoAddress, phoneDate, illicitCode, illicitBehavior, equipmentNumber, antifakeInformation);
            imageView.setImageBitmap(bitmap);
            //保存图片
            imageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    WatermarkSettings.savaWaterparkFile(filePath);
                    Toast.makeText(MainActivity.this, "您点击了图片,已保存", Toast.LENGTH_SHORT).show();
                }
            });
    
        }
    }
    

    ------------------------WatermarkSettings------------------------

    package com.example.zhuoshi.watermarkdemo;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Rect;
    import android.text.Layout;
    import android.text.StaticLayout;
    import android.text.TextPaint;
    import android.text.TextUtils;
    import android.util.DisplayMetrics;
    import android.util.Log;
    import android.view.WindowManager;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    /**
     * Author: baipenggui
     * Date: 2019/1/23 16:06
     * Email: 1528354213@qq.com
     * Description: 形成水印工具类
     */
    public class WatermarkSettings {
    
    
        public static WatermarkSettings mInstance;
        public static Context mContext;
        public static int mResources;
        private static String watermarkText;
        private static String mPhotoGraphed;
        private static String mPhotoDate;
        private static String mIllicitCode;
        private static String mIllicitBehavior;
        private static String mEquipmentNumber;
        private static String mAntifakeInformation;
        private static String TAG = "";
       /*
        *@Description: 图片添加水印的信息
        *@Params:
        *@Author: baipenggui
        *@Date: 2019/1/23
        */
        public static WatermarkSettings getmInstance(Context context) {
            mContext = context;
            if (mInstance == null) {
                mInstance = new WatermarkSettings();
            }
            TAG = mContext.getClass().getName();
            return mInstance;
        }
    
        /**
         * @Description 创建水印文件,以下是水印上添加的文本信息
         * @param resources 需要添加水印的图片资源
         * @param photoGraphed 拍照地点
         * @param photoDate 拍照时间
         * @param illicitCode 违法代码
         * @param illicitBehavior 违法行为
         * @param equipmentNumber 设备编号
         * @param antifakeInformation 防伪信息
         * @return
         */
        public static Bitmap createWatermark(int resources, String photoGraphed, String photoDate,
                                             String illicitCode, String illicitBehavior, String equipmentNumber, String antifakeInformation) {
            mResources = resources;
            mPhotoGraphed = photoGraphed;
            mPhotoDate = photoDate;
            mIllicitCode = illicitCode;
            mIllicitBehavior =  illicitBehavior;
            mEquipmentNumber = equipmentNumber;
            mAntifakeInformation = antifakeInformation;
            Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), resources);
            // 获取图片的宽高
            int bitmapWidth = bitmap.getWidth();
            int bitmapHeight = bitmap.getHeight();
            // 创建一个和图片一样大的背景图
            Bitmap bmp = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bmp);
            // 画背景图
            canvas.drawBitmap(bitmap, 0, 0, null);
            watermarkText = "违法时间:" + photoDate + "\n违法地点:" + photoGraphed + "\n违法代码:" + illicitCode + "\n违法行为:" + illicitBehavior + "\n设备编号:" + equipmentNumber + "\n防伪信息:" + antifakeInformation;
    
            //-------------开始绘制文字--------------
            if (!TextUtils.isEmpty(watermarkText)) {
                int screenWidth = getScreenWidth();
    
                float textSize = dp2px(mContext, 16) * bitmapWidth / screenWidth;
                // 创建画笔
                TextPaint mPaint = new TextPaint();
                // 文字矩阵区域
                Rect textBounds = new Rect();
                // 水印的字体大小
                mPaint.setTextSize(textSize);
                // 文字阴影
                mPaint.setShadowLayer(0.5f, 0f, 1f, Color.YELLOW);
                // 抗锯齿
                mPaint.setAntiAlias(true);
                // 水印的区域
                mPaint.getTextBounds(watermarkText, 0, watermarkText.length(), textBounds);
                // 水印的颜色
                mPaint.setColor(Color.BLUE);
                StaticLayout layout = new StaticLayout(watermarkText, 0, watermarkText.length(), mPaint, (int) (bitmapWidth - textSize),
                        Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.5F, true);
                // 文字开始的坐标
                float textX = dp2px(mContext, 8) * bitmapWidth / screenWidth;
                //float textY = bitmapHeight / 2;//图片的中间
                float textY = dp2px(mContext, 8) * bitmapHeight / screenWidth;
                // 画文字
                canvas.translate(textX, textY);
                layout.draw(canvas);
            }
            //保存所有元素
            canvas.save();
            canvas.restore();
            return bmp;
        }
    
        /**
         * @Description 保存水印图片
         * @param saveWatermarkPath 保存路径
         */
        public static void savaWaterparkFile(String saveWatermarkPath) {
    
            Bitmap watermark = createWatermark(mResources,mPhotoGraphed,mPhotoDate,mIllicitCode,mIllicitBehavior,mEquipmentNumber,mAntifakeInformation);
            File watermarkfile = new File(saveWatermarkPath);
            if (!watermarkfile.exists()) {
                watermarkfile.mkdir();
            }
            // 创建媒体文件名
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
            File file = new File(watermarkfile.getPath() + File.separator + timeStamp + ".jpg");
            if(file!=null){
                Log.e(TAG, "savaWaterparkFile: success ");
            }else{
                Log.e(TAG, "savaWaterparkFile: failure ");
            }
            BufferedOutputStream bos = null;
            try {
                bos = new BufferedOutputStream(new FileOutputStream(file));
                if (watermark != null) {
                    watermark.compress(Bitmap.CompressFormat.JPEG, 80, bos);
    
                }
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
    
            try {
                bos.flush();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
        }
    
        private static int getScreenWidth() {
            DisplayMetrics dm = new DisplayMetrics();
            WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
            wm.getDefaultDisplay().getMetrics(dm);
            return dm.widthPixels;
        }
    
        private static int dp2px(Context context, float dp) {
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dp * scale + 0.5f);
        }
    
    }
    

     -----------------------------activity_main-----------------------------

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:background="#cccccc"
        android:orientation="vertical">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:id="@+id/image"/>
    
    
    </LinearLayout>

     

    ---------------- babygirl.jpg --------------

     

     

     

    展开全文
  • 简单记录下给图片加水印的代码: public Bitmap addWaterMask(Bitmap src, long time, int resolution) { if (src == null) { return null; } int w = src.getWidth(); int h =



    简单记录下给图片加水印的代码:


    public Bitmap addWaterMask(Bitmap src, long time, int resolution) {
    
            if (src == null) {
                return null;
            }
            int w = src.getWidth();
            int h = src.getHeight();
            //需要处理图片太大造成的内存超过的问题,这里我的图片很小所以不写相应代码了
            Bitmap newb = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);// 创建一个新的和src宽度高度一样的位图
            Canvas cv = new Canvas(newb);
            cv.drawBitmap(src, 0, 0, null);// 在 0,0坐标开始画入src
    
            //加入文字
            Typeface font = Typeface.create("宋体", Typeface.NORMAL);
            TextPaint textPaint = new TextPaint();
            textPaint.setColor(Color.WHITE);
            textPaint.setTypeface(font);
    
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
            String mask = sdf.format(System.currentTimeMillis());
            if (time > 0) {
                mask = sdf.format(time);
            }
    
            if (resolution == 240) {
                textPaint.setTextSize(10);
                cv.drawText(mask, w - 120, h - 14, textPaint);
            } else if (resolution == 720) {
                textPaint.setTextSize(26);
                cv.drawText(mask, w - 310, h - 36, textPaint);
            } else if (resolution == 1088) {
                textPaint.setTextSize(40);
                cv.drawText(mask, w - 460, h - 56, textPaint);
            } else {
                textPaint.setTextSize(62);
                cv.drawText(mask, w - 720, h - 84, textPaint);
            }
    
            //这里是自动换行的
    //        StaticLayout layout = new StaticLayout(mask, textPaint, w, Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);
    //        layout.draw(cv);
    
    
            cv.save(Canvas.ALL_SAVE_FLAG);// 保存
            cv.restore();// 存储
            return newb;
    }


    上面代码给出了加水印的方法,其中参数说明如下:

    src - 需要加水印的Bitmap

    time - 加时间水印所需要的时间(其他样式类似)

    resolution - 图片分辨率(可用于判断水印大小和位置)


    可以看到其实加水印的处理流程还是比较简单的,不过是将Bitmap加载到Canvas中,

    然后用TextPaint(或者其他画笔)通过draw方法画上去,最后保存返回。其中注意点:

    注释中也说了,图片过大需要做防止内存溢出的操作,这是需要注意的,可做缓存或者

    其他类似的处理。(Canvas - 画布跟画家,Paint - 画笔,Bitmap - 要画的信息区域)



    这里参数是bitmap,可能需要一些简单的转换方法,毕竟很多时候图片都是以文件或者

    ImageView(Drawable等)形式存在的,这里罗列下:

    ImageView -> Bitmap @@@

    Bitmap image = ((BitmapDrawable)imageView.getDrawable()).getBitmap();

    可以看到这里先从ImageView得到Drawable,再得到Bitmap(这下也清楚如何将

    Drawable转换为Bitmap了= =),当然还有其他方法,可以参考以下链接:

    获取imageview里的Bitmap


    File(图片文件) -> Bitmap @@@

    public Bitmap getBitmap(File f, int width) {
    
            if (!f.exists()) {
                return null;
            }
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true; /* just decode bound , no memory use */
            BitmapFactory.decodeFile(f.getPath(), options); /* get image info to options */
    
            float realWidth = options.outWidth; /* here is the original size of this image */
            float realHeight = options.outHeight;
            float scale = 1;
            if (width > 0) scale = realWidth / width;
            if (scale <= 0)
                scale = 1;
            options.inSampleSize = (int) scale;
            options.inJustDecodeBounds = false; /* will really product an image , would use memory */
    
            return BitmapFactory.decodeFile(f.getPath(), options);
    }

    上面给出了图片文件转换为Bitmap的方法,参数说明:

    f - 需要转换的图片源文件

    width - 需要压缩的Bitmap宽度(这里只是通过宽度来判断scale来压缩,当然,高度也行)


    options.inJustDecodeBounds = true;
    设置的inJustDecodeBounds得值为true有何作用,看源码注释:


    大致意思就是设置为true后,最主要为了解码器后续解码时无需为图片的像素分配内存,

    通俗点讲就是为了得到图片的其他额外信息,而非图片的像素细节。


    BitmapFactory.decodeFile(f.getPath(), options);
    通过decodeFile即把图片文件的宽高等信息读入options中


    options.inSampleSize = (int) scale;
    这里设置要解码的Bitmap的scale,通过真实图片的width跟传入的width参数决定


            options.inJustDecodeBounds = false; /* will really product an image , would use memory */
    
            return BitmapFactory.decodeFile(f.getPath(), options);
    可以看到需要真正从文件解码到Bitmap时就需要像素信息了,将inJustDecodeBounds

    置为了false,然后解码返回。


    展开全文
  • 本文Android绘制Bitmap增加水印采用Paint画笔对图片进行绘制。 1.首先,创建一个画笔Paint对象 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);// paint.setColor(color);//Color.BLACK paint.setTextSize...

    本文Android绘制Bitmap增加水印采用Paint画笔对图片进行绘制。

    1.首先,创建一个画笔Paint对象

            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//
            paint.setColor(color);//Color.BLACK
            paint.setTextSize(20);//绘制文字大小
            Rect bounds = new Rect();
            paint.getTextBounds(text, 0, text.length(), bounds);//画笔的绘制范围
    //Paint.ANTI_ALIAS_FLAG :抗锯齿标志
    //Paint.FILTER_BITMAP_FLAG : 使位图过滤的位掩码标志
    //Paint.DITHER_FLAG : 使位图进行有利的抖动的位掩码标志
    //Paint.UNDERLINE_TEXT_FLAG : 下划线
    //Paint.STRIKE_THRU_TEXT_FLAG : 中划线
    //Paint.FAKE_BOLD_TEXT_FLAG : 加粗
    //Paint.LINEAR_TEXT_FLAG : 使文本平滑线性扩展的油漆标志
    //Paint.SUBPIXEL_TEXT_FLAG : 使文本的亚像素定位的绘图标志
    //Paint.EMBEDDED_BITMAP_TEXT_FLAG : 绘制文本时允许使用位图字体的绘图标志
    

    2.在Bitmap上绘制文字

        //绘制文字
        private static Bitmap drawTextToBitmap(Bitmap bitmap, String text, Paint paint, int paddingLeft, int paddingTop) {
            Bitmap.Config bitmapConfig = bitmap.getConfig();
            paint.setDither(true); // 获取跟清晰的图像采样
            paint.setFilterBitmap(true);// 过滤
            if (bitmapConfig == null) {
                bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
            }
            bitmap = bitmap.copy(bitmapConfig, true);
            Canvas canvas = new Canvas(bitmap);
            canvas.drawText(text, paddingLeft, paddingTop, paint);
            return bitmap;
    
        }

    3.最后看下效果

    展开全文
  • android中如何给图片添加水印,下面截取了部分核心代码,仅供参考: /**  * 获取图片缩小的图片  * @param src  * @return  */  public static Bitmap scaleBitmap(String src)  {  //获取图片...

    在android中如何给图片添加水印,下面截取了部分核心代码,仅供参考:


    /**
         * 获取图片缩小的图片
         * @param src
         * @return
         */
        public static Bitmap scaleBitmap(String src)
        {
            //获取图片的高和宽
            BitmapFactory.Options options = new BitmapFactory.Options();
            //这一个设置使 BitmapFactory.decodeFile获得的图片是空的,但是会将图片信息写到options中
            options.inJustDecodeBounds = true;        
            BitmapFactory.decodeFile(src, options); 
            options.inSampleSize = 1;
            //设置可以获取数据
            options.inJustDecodeBounds = false;
            //获取图片
            return BitmapFactory.decodeFile(src, options);        
        }
        /**
         * 加水印 也可以加文字
         * @param src
         * @param watermark
         * @param title
         * @return
         */
        public static Bitmap watermarkBitmap(Bitmap src, Bitmap watermark,
                String title) {
            if (src == null) {
                return null;
            }
            int w = src.getWidth();
            int h = src.getHeight(); 
            //需要处理图片太大造成的内存超过的问题,这里我的图片很小所以不写相应代码了        
            Bitmap newb= Bitmap.createBitmap(w, h, Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
            Canvas cv = new Canvas(newb);
            cv.drawBitmap(src, 0, 0, null);// 在 0,0坐标开始画入src    
            Paint paint=new Paint();
            //加入图片
            if (watermark != null) {
                int ww = watermark.getWidth();
                int wh = watermark.getHeight();
                paint.setAlpha(50);
    //            cv.drawBitmap(watermark, w - ww + 5, h - wh + 5, paint);// 在src的右下角画入水印         
                cv.drawBitmap(watermark, 0, 0, paint);// 在src的左上角画入水印      
            }else{
            Log.i("i", "water mark failed");
            }
            //加入文字
            if(title!=null)
            {
                String familyName ="宋体";
                Typeface font = Typeface.create(familyName,Typeface.NORMAL);            
                TextPaint textPaint=new TextPaint();
                textPaint.setColor(Color.RED);
                textPaint.setTypeface(font);
                textPaint.setTextSize(40);
                //这里是自动换行的
    //            StaticLayout layout = new StaticLayout(title,textPaint,w,Alignment.ALIGN_OPPOSITE,1.0F,0.0F,true);
    //            layout.draw(cv);
                //文字就加左上角算了
                cv.drawText(title,w-400,h-40,textPaint); 
            }
            cv.save(Canvas.ALL_SAVE_FLAG);// 保存
            cv.restore();// 存储
            return newb;
        }

    展开全文
  • Android 图片添加水印

    2019-01-14 15:21:02
    ImageUtil 工具类 package ... import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics....
  • Android图片加图片logo水印,可以加文字水印,左上角,右上角,中间,左下角,右下角
  • * 左下角添加水印(多行,图标 + 文字) * 参考资料: * Android 对Canvas的translate方法总结 https://blog.csdn.net/u013681739/article/details/49588549 * @param photo */ public static...
  • Android图片添加水印图片并把图片保存到文件存储package zhangphil.test; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.os.Bundle; ...
  • Android 图片加水印

    2014-08-27 09:37:22
    Android 图片加水印 首先可以肯定 java.awt 在android中是不可用的 直接上代码: /** * * @param src 原图片 * @param watermark 要打的水印图片 * @param title 要打的水印文字 * @param densityDpi ...
  • Android 添加水印图片

    2019-08-16 13:57:45
    * 给图片加水印 * 水印位置根据服务端给的处理 * @param src 原图 * @param watermark 水印 * @return 加水印的原图 */ public Bitmap WaterMask(Bitmap src, Bitmap watermark) { in...
  • Android图片添加文字水印并保存水印文字图片到指定文件package zhangphil.test; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android....
  • android图片添加水印

    2020-07-09 23:31:08
    实现View的拖拽,放大,缩小、保存至本地。
  • Android添加图片水印

    2017-10-16 16:58:31
    最近做了一些需求,记录下来,需求是:从手机相册选取一些图片,然后给这些图片添加水印,然后将添加后的图片BitMap转化成byte上传到阿里云,从阿里云拿到地址,然后再将图片地址上传到我们自己的服务器。...
  • 图片增加水印我们可以通过canvas来绘制,首先我们新创建一个工具类: object WaterMarkHelper { fun createWaterMaskBitmap(context: Activity?, src: Bitmap, watermark: String, paddingLeft: Int, ...
  • public static Bitmap drawImageToBitmap(Bitmap bitmap, Bitmap waterBitmap) { android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig(); if (bitmapConfig == null) { bitmapConfig =
  • 相信大家都了解通过canvas和bitmap,为图片添加水印的实现方式,十分方便,但是在产品化的代码中,它的耗时就成为了最大的痛点。接下来为大家介绍一种十分高效的方法,通过YUV buffer拷贝添加水印。(1)首先,获取...
  • 本文主要内容:1、使用两张图片合成水印。 2、将文字直接绘制到图片上。3、获取手机或sd卡上的图片,压缩并显示。 好了,废话不多说,直接上代码,在代码中都有详细的注释 以下是使用两张图片合成水印 /** *...
  • Stamper是一个给图片水印的工具,支持图片水印和文字水印水印位置可以任意调节。 效果图: 实现原理: Stamper将原图当作画布,把水印图或者文字画入原图中。生成bitmap。 Stamper使用方法: 1.添...
1 2 3 4 5 ... 20
收藏数 3,214
精华内容 1,285