Android 如何在 Canvas里 放多张图片

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 如何在 Canvas里 放多张图片相关的知识,希望对你有一定的参考价值。

方案只有一种:

1、图片转换为Bitmap对象

2、通过canvas的drawBitmap方法绘制图片对象

示例:

1、图片转换成Bitmap对象
 1)资源文件转换
Bitmap bmp=BitmapFactory.decodeResource(r, R.drawable.icon);//读取drawable下的icon图片,转换为bitmap对象
 2)根据路径转换
 public Bitmap convertToBitmap(String path, int w, int h) 
      BitmapFactory.Options opts = new BitmapFactory.Options();      
      opts.inJustDecodeBounds = true;// 设置为ture只获取图片大小
      opts.inPreferredConfig = Bitmap.Config.ARGB_8888;//颜色值
      BitmapFactory.decodeFile(path, opts);//返回为空,opts返回图片大小。
      int width = opts.outWidth;//图片实际宽度
      int height = opts.outHeight;//图片实际高度
      float scaleWidth = 0.f, scaleHeight = 0.f;
      if (width > w || height > h) //缩放图片
          // 缩放
          scaleWidth = ((float) width) / w;
          scaleHeight = ((float) height) / h;
      
      opts.inJustDecodeBounds = false;//设置缩放图片
      float scale = Math.max(scaleWidth, scaleHeight);
      opts.inSampleSize = (int)scale;//设置缩放比例
      WeakReference<Bitmap> weak = new WeakReference<Bitmap>(BitmapFactory.decodeFile(path, opts));//获取图片的弱引用,便于释放图片占用内存
      return Bitmap.createScaledBitmap(weak.get(), w, h, true);//返回图片对象
  
2、canvas上绘制图片
 Bitmap bmp;//获取的bitmap对象
 Paint p;//定义画笔
 canvasTemp.drawBitmap(bmp, 50, 50, p);//在50,50位置绘制图片

参考技术A 是的,第二张图片只有整个canvas的一半,而且想让它半透明 参考技术B 用canvas画多张图的时候一定要注意recycle,不然很容易出现内存溢出的错误。

dalvik虚拟机中一个线程只能占12M的空间,android中的图片的显示最后显示出来的都是bitmap格式,都是通过底层的C来实现的,而用来显示图片的内存空间只被分配了4M,所以你画图时一定要考虑图片的大小,把不用的都给recycle掉,不然当等待虚拟机自动回收的时候,很可能已经抛out of memory 错误了
参考技术C 用canvas画多张图的时候一定要注意recycle,不然很容易出现内存溢出的错误。

dalvik虚拟机中一个线程只能占12M的空间,android中的图片的显示最后显示出来的都是bitmap格式,都是通过底层的C来实现的,而用来显示图片的内存空间只被分配了4M,所以你画图时一定要考虑图片的大小,把不用的都给recycle掉,不然当等待虚拟机自动回收的时候,很可能已经抛out of memory 错误了追问

我想有一个Gallery 然后点一个 在Canvas里显示 点一个显示 这个不行啊 怎么弄啊

追答

你可以研究 api demos里的gallery例子

ApiDemos\src\com\example\android\apis\view\Gallery1.java

参考技术D canvas.drawbitmap可以随便你怎么画图像啊。追问

我想有一个Gallery 然后点一个 在Canvas里显示 点一个显示 这个不行啊 怎么弄啊

js多张图片合成一张图,canvas(海报图,将二维码和背景图合并) -----vue

思路:vue中图片合并

  首先准备好要合并的背景图,和请求后得到的二维码,

        canvas画图,将两张背景图和一张二维码用canvas画出来,

        将canvas再转为img

        注意canvas和图片的清晰图和图片的尺寸位置

       开始时canvas是隐藏的,两张背景图时显示的,当canvas画完后再转为img的时候,隐藏canvas和背景图,显示canvas转完的图片(也就是合并后的图片)

       这个适配方式可能有些瑕疵,所以会加了很多设备的判断

代码:

  html

    

<div class="wap-poster" ref="imageWrapper" id="target" style="width: 100%;">
    <canvas id="mycanvas" width="100%" height="100%" v-if="!infactQrCode" style="transform: scale(2);display: none"></canvas>
    <img  v-if="!infactQrCode"  src="../../../assets/imgs/posterbg.jpg" id="bgImg" alt="" style="width: 100%;height:100%;">
    <img  v-if="!infactQrCode"  src="../../../assets/imgs/poster0.png" id="poster" alt="" style="position: absolute;">
    <img  v-if="!infactQrCode" id="qrcode" :src="qrCodeImg" alt="" style="position: absolute;top:247px;width: 140px;height: 140px;display: none">
    <img :src="infactQrCode" alt="" v-if="infactQrCode" style="width: 100%;height:100%">
  </div>

 

 

      js<script>

  import html2canvas from  html2canvas
  export default 
    name: Poster,
    data() 
      return 
        qrCodeImg: "",
        infactQrCode:"",
      
    ,
    created()
    
//二维码图片后台返回 this.qrCodeImg="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1568183940&di=49b7187fdb7fee3e30c20583150f09b6&imgtype=jpg&er=1&src=http%3A%2F%2Fdown.admin5.com%2Fuploads%2Fallimg%2F170630%2F2160_170630144656_1.jpg"; , methods: drawImg() let _self=this; var canvas = document.getElementById("mycanvas"); var a = setInterval(() => // 重复获取 canvas = document.getElementById("mycanvas"); if(!canvas) return false else clearInterval(a); var context = canvas.getContext(2d); context.scale(2,2) //图片清晰度解决办法,缩放2倍后,其他图片的宽高也要比ui设计的宽高乘以2 var img = new Image(); img.setAttribute(crossOrigin, anonymous); let bgUrl=document.getElementById("bgImg").src; img.src=bgUrl; img.onload = function() if(img.complete)
          //画第一张背景图,图片的宽高撑满整个屏幕   context.drawImage(img,
0,0,window.screeWidth,window.screeHeight); var img1 = new Image(); let bgUrl1=document.getElementById("poster"); img1.src=bgUrl1.src; img1.setAttribute(crossOrigin, anonymous); img1.onload = function()
            //img1为第2张背景图,开始画第2张图,图片的的定位,left为整个屏幕-ui设计图片的宽*图片的适配比例,最后除以2保证图片居中,
            //图片的left top width height都是这样计算的,
if(img1.complete) var left = (window.screeWidth-600*window.rateWidth)/2; if(window.screeHeight>=812&&window.screeWidth<768) //iphonx的计算方式 context.drawImage(img1,left,200*window.rateWidth,600*window.rateWidth,890*window.rateHeight); else context.drawImage(img1,left,110*window.rateWidth,600*window.rateWidth,1100*window.rateHeight); var img2 = new Image(); img2.src=document.getElementById("qrcode").src; img2.crossOrigin="*"; img2.onload = function() if(img2.complete)
              //二维码图片的画图left top widht height
var left = (window.screeWidth-290*window.rateWidth)/2; if(window.screeWidth==600&&window.screeHeight==1024) //ipad var left = (window.screeWidth-240*window.rateWidth)/2; context.drawImage(img2,left,460*window.rateHeight,240*window.rateWidth,240*window.rateWidth); var image = new Image(); _self.infactQrCode=canvas.toDataURL("image/png"); return if(window.screeWidth>=768&&window.screeHeight>812) //其他设备 var left = (window.screeWidth-230*window.rateWidth)/2; context.drawImage(img2,left,430*window.rateHeight,230*window.rateWidth,230*window.rateWidth); else if (window.screeHeight>=812&&window.screeWidth<768) context.drawImage(img2,left,410*window.rateHeight,290*window.rateWidth,290*window.rateWidth); else context.drawImage(img2,left,410*window.rateHeight,290*window.rateWidth,290*window.rateWidth);

              //以上为2张背景图和一张二维码画合并后图画到canvas的结果,下面为将canvas转为图片的方法
var image = new Image(); _self.infactQrCode=canvas.toDataURL("image/png"); ,1) , , mounted() this.drawImg(); //主要代码再该方法,将图片转为canvas,再将canvas转为图片,因为canvas是无法长按保存和识别二维码的 const that = this; window.screeWidth=window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; window.screeHeight= window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; var left = (window.screeWidth-140)/2; var qrcode=document.getElementById("qrcode"); qrcode.style.left=left+px; this.screeWidth=window.screeWidth; var canvas = document.getElementById("mycanvas");
//适配 window.rateWidth
= window.screeWidth/ 750; window.rateHeight = window.screeHeight/1334;
//清晰度解决办法 canvas.setAttribute(
"width",window.screeWidth*2); canvas.setAttribute("height",window.screeHeight*2);



let bgUrl1
=document.getElementById("poster"); var left = (window.screeWidth-600*window.rateWidth)/2; if(window.screeHeight>=812&&window.screeWidth<768) bgUrl1.style.left=left+"px"; bgUrl1.style.top=200*window.rateWidth+"px"; bgUrl1.style.width=600*window.rateWidth+"px"; bgUrl1.style.height=890*window.rateHeight+"px"; else bgUrl1.style.left=left+"px"; bgUrl1.style.top=110*window.rateWidth+"px"; bgUrl1.style.width=600*window.rateWidth+"px"; bgUrl1.style.height=1100*window.rateHeight+"px"; , </script>

 

以上是关于Android 如何在 Canvas里 放多张图片的主要内容,如果未能解决你的问题,请参考以下文章

如何将Canvas 上的内容转换为一张Bitmap-Android开发问答

Word怎样在一张纸上放多张图片

canvas 多张图片绘制层级问题

移动端 canvas插入多张图片生成一张可保存到手机图片

如何使用 Flutter 在 iOS 和 Android 上共享多张图片?

js多张图片合成一张图,canvas(海报图,将二维码和背景图合并) -----vue