精华内容
下载资源
问答
  • 生成海报

    2019-07-31 23:23:59
    上一章讲了如何生成二维码,这里才讲如何生成海报,有时候我们需要把海报做出推广的效果,让客户用着舒服,这个时候就需要生成海报,废话不多说,直接上代码 前端:只是放一个图片的路径(为了方便) <div ...

    上一章讲了如何生成二维码,这里才讲如何生成海报,有时候我们需要把海报做出推广的效果,让客户用着舒服,这个时候就需要生成海报,废话不多说,直接上代码

    前端:只是放一个图片的路径(为了方便)

    
    <div class="row" style="width:250Px;margin:auto">
        <img id="imgPoster" src="@Url.Action("ShowImg", "Home")" />
    </div>

    后台:

            public ActionResult Index()
            {
                return View();
            }
    
            /// <summary>
            ///  显示图片
            /// </summary>
            /// <returns></returns>
            public ActionResult ShowImg()
            {
                string url = "https://www.baidu.com";
                //var bytes = QrCode.GetQrCode(url);
                //Stream imgStream = new MemoryStream(bytes);
                //return File(imgStream, "image/jpeg");
                QrCode code = new QrCode();
                var imgStream = code.GetRecommendQrCodeText("", url, "张三");//这里第一个参数传递空,后面用了判断,如果有图片直接拿自己的链接即可
                return File(imgStream, "image/jpeg");//还是一样转换成流的形式
            }

    接下来就是用画布来画文字,图片,头像,二维码,

    看着下面那么多代码不要怕,很多都是把资源画到画布上面去,直接拿过去copy即可

    里面的方法已经注释的很清晰了

    需要注意的是TemplateImageBytes这个对象声明时,获取画布,我在里面放了一张背景图,如果你有好看的图片自己放上去即可

        public class QrCode
        {
            /// <summary>
            /// 二维码图片流
            /// </summary>
            /// <param name="userAvater">头像</param>
            /// <param name="url">地址</param>
            /// <param name="storeName">姓名</param>
            /// <param name="templateImg">海报背景图</param>
            /// <returns></returns>
            public Stream GetRecommendQrCodeText(string userAvater, string url, string storeName)
            {
                if (string.IsNullOrWhiteSpace(userAvater) || userAvater == "null")
                    userAvater = "/Image/personalImg.png";
    
                return GetRecommendQrCode(userAvater, url, storeName, (templateImage) =>
                {
                    //获取头像
                    byte[] _avaterImageBytes = GetOtherImgThum(userAvater, 120, 120, false);
    
                    //获取二维码
                    byte[] _codeImageBytes = GetQrCode(url, 190, 190, 0);
                    //把头像画进画布
                    templateImage = PaintImage(templateImage, _avaterImageBytes, 76, 409);
    
                    //把二维码画进画布
                    templateImage = PaintImage(templateImage, _codeImageBytes, 370, 409);
                
    
                    templateImage = WriteTextInImage(templateImage,"一起研究海报是怎样生成的", "微软雅黑", 28, 76, 76, 76, 110, 100);
                    templateImage = WriteTextInImage(templateImage, storeName+"邀请你一起关注右右下方的二维码", "微软雅黑", 23, 76, 76, 76, 120, 209);
                    templateImage = WriteTextInImage(templateImage, "用手机扫描识别", "微软雅黑", 23, 76, 76, 76, 195, 409);
    
                    return templateImage;
                });
            }
    
            /// <summary>
            /// 获取推广二维码图片流
            /// </summary>
            /// <param name="userAvater"></param>
            /// <param name="userName"></param>
            /// <param name="url"></param>
            /// <param name="storeName"></param>
            /// <param name="fuc"></param>
            /// <returns></returns>
            public Stream GetRecommendQrCode(string userAvater, string url, string storeName,Func<Image, Image> fuc = null)
            {
    
                System.Drawing.Image templateImage = System.Drawing.Image.FromStream(new System.IO.MemoryStream(TemplateImageBytes));
    
                if (fuc != null)
                {
                    //写入文字或图片写入到背景图上
                    templateImage = fuc(templateImage);
                }
    
                var ms = new MemoryStream();
                templateImage.Save(ms, ImageFormat.Png);
                templateImage.Dispose();
                ms.Position = 0;
                return ms;
            }
    
            /// <summary>
            /// 获取外域图片,并生产缩略图
            /// </summary>
            /// <param name="url">图片路径</param>
            /// <param name="width">宽度</param>
            /// <param name="height">高度</param>
            /// <param name="isImageAvater">是否变成圆形 传true图片变成圆形</param>
            /// <returns></returns>
            private static byte[] GetOtherImgThum(string url, int width = 250, int height = 250, bool isImageAvater = true)
            {
                if (!url.ToLower().StartsWith("http://") && !url.ToLower().StartsWith("https://"))
                {
                    //获取画布
                    string templatePath = GetMapPath(url);
    
                    return System.IO.File.ReadAllBytes(templatePath);
                }
    
                System.Net.WebClient wc = new System.Net.WebClient();
                byte[] bs = wc.DownloadData(url);
    
                System.Drawing.Image img = System.Drawing.Image.FromStream(new System.IO.MemoryStream(bs));
                int srcWidth = img.Width;
                int srcHeight = img.Height;
                System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height);
                System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(bmp);
                try
                {
                    gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                    System.Drawing.Rectangle rectDestination = new System.Drawing.Rectangle(0, 0, width, height);
                    gr.DrawImage(img, rectDestination, 0, 0, srcWidth, srcHeight, System.Drawing.GraphicsUnit.Pixel);
                    if (!isImageAvater)
                    {
                        int r = Math.Min(bmp.Width, bmp.Height) / 2;
                        PointF c = new PointF(bmp.Width / 2.0F, bmp.Height / 2.0F);
                        for (int h = 0; h < bmp.Height; h++)
                            for (int w = 0; w < bmp.Width; w++)
                                if ((int)Math.Pow(r, 2) < ((int)Math.Pow(w * 1.0 - c.X, 2) + (int)Math.Pow(h * 1.0 - c.Y, 2)))
                                {
                                    bmp.SetPixel(w, h, Color.Transparent);
                                }
                    }
                    using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
                    {
                        bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                        return ms.ToArray();
                    }
                }
                catch (Exception e)
                {
                    throw e;
                }
                finally
                {
                    img.Dispose();
                    gr.Dispose();
                    bmp.Dispose();
                }
            }
    
            /// <summary>
            ///  把图片画进画布里
            /// </summary>
            /// <param name="templateImage"></param>
            /// <param name="_markByte"></param>
            /// <param name="posX"></param>
            /// <param name="posY"></param>
            /// <returns></returns>
            private Image PaintImage(System.Drawing.Image templateImage, byte[] _markByte, int posX, int posY)
            {
                System.Drawing.Image avaterImage = System.Drawing.Image.FromStream(new System.IO.MemoryStream(_markByte));
    
                System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(templateImage);
                //设置高质量插值法
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                //设置高质量,低速度呈现平滑程度
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
    
                System.Drawing.Imaging.ImageAttributes imageAttributes = new System.Drawing.Imaging.ImageAttributes();
                try
                {
                    float[][] colorMatrixElements = {
                                                    new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
                                                    new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
                                                    new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
                                                    new float[] {0.0f,  0.0f,  0.0f,  1.0f, 0.0f},
                                                    new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
                                                };
    
                    System.Drawing.Imaging.ColorMatrix colorMatrix = new System.Drawing.Imaging.ColorMatrix(colorMatrixElements);
                    imageAttributes.SetColorMatrix(colorMatrix, System.Drawing.Imaging.ColorMatrixFlag.Default, System.Drawing.Imaging.ColorAdjustType.Bitmap);
    
                    g.DrawImage(avaterImage, new System.Drawing.Rectangle(posX, posY, avaterImage.Width, avaterImage.Height), 0, 0, avaterImage.Width, avaterImage.Height, System.Drawing.GraphicsUnit.Pixel, imageAttributes);
    
                    return templateImage;
                }
                catch (Exception e)
                {
                    throw e;
                }
                finally
                {
                    avaterImage.Dispose();
                    g.Dispose();
                    imageAttributes.Dispose();
                }
            }
    
            /// <summary>
            /// 把文字画进画布
            /// </summary>
            /// <param name="templateImage"></param>
            /// <param name="text"></param>
            /// <param name="fontname"></param>
            /// <param name="fontsize"></param>
            /// <param name="red"></param>
            /// <param name="green"></param>
            /// <param name="blue"></param>
            /// <param name="posX"></param>
            /// <param name="posY"></param>
            /// <returns></returns>
            private Image WriteTextInImage(System.Drawing.Image templateImage, string text, string fontname, int fontsize, int red, int green, int blue, int posX, int posY)
            {
                System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(templateImage);
                //设置高质量插值法
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                //设置高质量,低速度呈现平滑程度
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
    
                try
                {
                    System.Drawing.Font drawFont = new System.Drawing.Font(fontname, fontsize, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Pixel);
                    System.Drawing.SizeF crSize;
                    crSize = g.MeasureString(text, drawFont);
    
                    g.DrawString(text, drawFont, new System.Drawing.SolidBrush(System.Drawing.Color.FromArgb(red, green, blue)), posX, posY);
    
                    return templateImage;
                }
                catch (Exception e)
                {
                    throw e;
                }
                finally
                {
                    g.Dispose();
                }
            }
    
            /// <summary>
            /// 生成二维码
            /// </summary>
            /// <param name="qrValue">二维码内容</param>
            /// <param name="height">二维码高度,默认250</param>
            /// <param name="width">二维码宽度,默认250</param>
            /// <param name="margin">二维码边距,默认0</param>
            /// <param name="logo">logo图片 有就加没有就算了</param>
            /// <returns></returns>
            public static byte[] GetQrCode(string qrValue = "https://www.baidu.com", int height = 250, int width = 250, int margin = 0, byte[] logo = null)
            {
    
                // 1.设置QR二维码的规格
                var qrEncodeOption = new ZXing.QrCode.QrCodeEncodingOptions();
                qrEncodeOption.CharacterSet = "UTF-8"; // 设置编码格式,否则读取'中文'乱码
                qrEncodeOption.Height = height;
                qrEncodeOption.Width = width;
                qrEncodeOption.Margin = margin; // 设置周围空白边距
    
                // 2.生成条形码图片并保存
                var wr = new ZXing.BarcodeWriter();
                wr.Format = ZXing.BarcodeFormat.QR_CODE; // 二维码
                wr.Options = qrEncodeOption;
    
                using (Bitmap img = wr.Write(qrValue))
                {
                    if (logo != null)
                    {
                        // 3.在二维码的Bitmap对象上绘制logo图片
                        var logoImg = System.Drawing.Image.FromStream(new System.IO.MemoryStream(logo)) as Bitmap;
                        //var logoImg = Bitmap.FromFile(logo) as Bitmap;
                        var g = Graphics.FromImage(img);
                        var logoRec = new Rectangle(); // 设置logo图片的大小和绘制位置
                        logoRec.Width = img.Width / 6;
                        logoRec.Height = img.Height / 6;
                        logoRec.X = img.Width / 2 - logoRec.Width / 2; // 中心点
                        logoRec.Y = img.Height / 2 - logoRec.Height / 2;
                        g.DrawImage(logoImg, logoRec);
                    }
    
                    using (var stream = new System.IO.MemoryStream())
                    {
                        img.Save(stream, System.Drawing.Imaging.ImageFormat.Gif);
                        return stream.ToArray();
                    }
                }
            }
    
            
            //锁对象
            private static object lockHelper = new object();
            private static byte[] templateImageBytes;
            private byte[] TemplateImageBytes
            {
                get
                {
                    if (templateImageBytes == null)
                    {
                        lock (lockHelper)
                        {
                            if (templateImageBytes == null)
                            {
                                string templateImg = "/Image/tem.jpg";
                                //获取画布
                                string templatePath = GetMapPath(templateImg);
    
                                templateImageBytes = System.IO.File.ReadAllBytes(templatePath);
                            }
                        }
                    }
    
                    return templateImageBytes;
                }
            }
            
            /// <summary>
            /// 获取画布
            /// </summary>
            /// <param name="path"></param>
            /// <returns></returns>
            public static string GetMapPath(string path)
            {
                if (path.ToLower().StartsWith("http://"))
                {
                    return path;
                }
                if (HttpContext.Current != null)
                {
                    return HttpContext.Current.Server.MapPath(path);
                }
                else //非web程序引用
                {
                    path = AppDomain.CurrentDomain.BaseDirectory + path.Replace("/", "\\");
                    return path;
                }
            }
        }

    看效果

     

     

    虽然难看了一点,x轴、y轴都是可以 自己调的,还有背景图可以自己换

     

    百度网盘链接:

    链接:https://pan.baidu.com/s/1vkvZK7JemlcoM4rqeGGYNg 
    提取码:7112 

    展开全文
  • 1.h5生成海报 <div id="qrcodeCanvas" style="position: absolute;left:-2000px"></div> <!--海报图画布--> <canvas id="myCanvas" style="position: absolute;right:-2000px"></...

    1.h5生成海报

     <div id="qrcodeCanvas" style="position: absolute;left:-2000px"></div>
        <!--海报图画布-->
        <canvas id="myCanvas" style="position: absolute;right:-2000px"></canvas>
         <div class="showPoster"><img id="showImg" />
     <div>
    <script type="text/javascript" src="./js/jquery.js"></script>
    <script src="./js/showLoading/showLoading/jquery.showLoading.min.js"></script>
    <script src="./js/showLoading/showLoading/jquery.showLoading.js"></script>
    <script type="text/javascript" src="./js/qrcode.js"></script>
    <script type="text/javascript">
        var qrcodeImg    //二维码img
        shareImg();
        function shareImg(){
            $('#showImg').showLoading('图片生成中...');
            //移除已生成的避免重复(必须!)
            $('#qrcodeCanvas').html("");
            var qrcode = new QRCode('qrcodeCanvas', {
                text: "二维码内容",
                width: 100,
                height: 100,
                colorDark: '#000000',
                colorLight: '#ffffff',
                correctLevel: QRCode.CorrectLevel.H
            });
            qrcodeImg = $("#qrcodeCanvas img")[0]
            qrcodeImg.crossOrigin = "anonymous"
            console.log(qrcodeImg)
            //这里必须用onload 二维码是异步生成,异步的意思不用多说吧?
            qrcodeImg.onload = function() {
                //画海报
                beginDraw()
            }
        }
        function beginDraw(){
            //画海报
            var width  = 320
            var height = 450
            var c      = document.getElementById("myCanvas");
            c.width    = width
            c.height   = height
            var ctx    = c.getContext("2d");
            //首先画上背景图
            //注意:H5中任何图片写入画布都是以img 例如(<img src="123.png">),以下代码console.log() 出来就是它
            var img = new Image();
            img.src = '图片地址';
            img.crossOrigin = "anonymous"
            img.onload = function() {
                //画入背景图
                ctx.drawImage(img,0,0,width,height);
                img.src = '图片地址';
                img.crossOrigin = "anonymous"
                img.onload = function() {
                    //画入logo
                    ctx.drawImage(img,90,30,150,140);
                    img.src = '图片地址';
                    img.crossOrigin = "anonymous"
                    img.onload = function() {
                        //画入底部背景
                        ctx.drawImage(img,0,height-180,width,120);
                        img.src = '图片地址';
                        img.crossOrigin = "anonymous"
                        img.onload = function() {
                            //画入头像
                            ctx.drawImage(img,10,height-155,70,70);
                            //画入二维码
                            ctx.drawImage(qrcodeImg,210,height-170,100,100);
                            ctx.font ="18px Bold Arial";
                            ctx.fillStyle = "#fff";
                            ctx.fillText("文字",40,height-220);
                            ctx.font ="18px Medium Arial";
                            ctx.fillStyle = "#000";
                            ctx.fillText("文字",90,height-130);
                            ctx.font ="18px Medium Arial";
                            ctx.fillStyle = "#000";
                            ctx.fillText("文字 ",90,height-90);
                            //绘制完成,转为图片
                            setTimeout(function() {
                                base64_path = c.toDataURL("image/jpeg",1);
                                $('#showImg').attr('src',base64_path)
                                $('#showImg').hideLoading();
                                $('.mask').show()
                                $('.showPoster').show()
                            },100)
    
                        }
                    }
                }
            }
        }
    </script>

    2.本以为大功告成 结果部分安卓手机在这里不执行

            qrcodeImg.onload = function() {
                //画海报
                beginDraw()
            } 

    搜了一大顿资料,参考移动端File和Base64的坑  可能会解决吧

    我就不试了

    3.直接后台生成吧

            $new_file_name = $fiel_dir .$file_name;
            $fontpath = realpath('./ttf/simsunb.ttf');
    //        $fontpath = 'https://cummins.weimobile.cc/ttf/arial.ttf';
            $config = array(
                'text'=>array(
                    array(
                        'text'=>'文字',
                        'left'=>23,
                        'top'=>330,
                        'fontPath'=>$fontpath,     //字体文件
                        'fontSize'=>22,             //字号
                        'fontColor'=>'255,255,255',       //字体颜色
                        'angle'=>0,
                    ),
    
                ),
                'image'=>array(
                    array(
                        'url'=> '图片地址',//kmslogo
                        'left'=>120,
                        'top'=>60,
                        'stream'=>0,             //图片资源是否是字符串图像流
                        'right'=>0,
                        'bottom'=>0,
                        'width'=>150,
                        'height'=>150,
                        'opacity'=>100
                    ),
                    
                ),
                'background'=>'背景图路径',
            );
            $filename=createPoster($config,$new_file_name);
    /**
     * 生成宣传海报
     * @param array  参数,包括图片和文字
     * @param string  $filename 生成海报文件名,不传此参数则不生成文件,直接输出图片
     * @return [type] [description]
     */
    function createPoster($config=array(),$filename=""){
        //如果要看报什么错,可以先注释调这个header
        if(empty($filename))
            header("content-type: image/png");
        $imageDefault = array(
            'left'=>0,
            'top'=>0,
            'right'=>0,
            'bottom'=>0,
            'width'=>100,
            'height'=>100,
            'opacity'=>100
        );
        $textDefault = array(
            'text'=>'',
            'left'=>0,
            'top'=>0,
            'fontSize'=>32,       //字号
            'fontColor'=>'255,255,255', //字体颜色
            'angle'=>0,
        );
        $background = $config['background'];//海报最底层得背景
        //背景方法
        $backgroundInfo = getimagesize($background);
        $backgroundFun = 'imagecreatefrom'.image_type_to_extension($backgroundInfo[2], false);
        $background = $backgroundFun($background);
        $backgroundWidth = imagesx($background);  //背景宽度
        $backgroundHeight = imagesy($background);  //背景高度
        $imageRes = imageCreatetruecolor($backgroundWidth,$backgroundHeight);
        $color = imagecolorallocate($imageRes, 0, 0, 0);
        imagefill($imageRes, 0, 0, $color);
        // imageColorTransparent($imageRes, $color);  //颜色透明
        imagecopyresampled($imageRes,$background,0,0,0,0,imagesx($background),imagesy($background),imagesx($background),imagesy($background));
        //处理了图片
        if(!empty($config['image'])){
            foreach ($config['image'] as $key => $val) {
                $val = array_merge($imageDefault,$val);
                $info = getimagesize($val['url']);
                $function = 'imagecreatefrom'.image_type_to_extension($info[2], false);
                if($val['stream']){   //如果传的是字符串图像流
                    $info = getimagesizefromstring($val['url']);
                    $function = 'imagecreatefromstring';
                }
                $res = $function($val['url']);
                $resWidth = $info[0];
                $resHeight = $info[1];
                //建立画板 ,缩放图片至指定尺寸
                $canvas=imagecreatetruecolor($val['width'], $val['height']);
                imagefill($canvas, 0, 0, $color);
                //关键函数,参数(目标资源,源,目标资源的开始坐标x,y, 源资源的开始坐标x,y,目标资源的宽高w,h,源资源的宽高w,h)
                imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'],$resWidth,$resHeight);
                $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']) - $val['width']:$val['left'];
                $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']) - $val['height']:$val['top'];
                //放置图像
                imagecopymerge($imageRes,$canvas, $val['left'],$val['top'],$val['right'],$val['bottom'],$val['width'],$val['height'],$val['opacity']);//左,上,右,下,宽度,高度,透明度
            }
        }
        //处理文字
        if(!empty($config['text'])){
            foreach ($config['text'] as $key => $val) {
                $val = array_merge($textDefault,$val);
                list($R,$G,$B) = explode(',', $val['fontColor']);
                $fontColor = imagecolorallocate($imageRes, $R, $G, $B);
                $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']):$val['left'];
                $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']):$val['top'];
    //            imagettftext($imageRes,$val['fontSize'],$val['angle'],$val['left'],$val['top'],$fontColor,'STHUPO.TTF',$val['text']);
                imagettftext($imageRes,$val['fontSize'],$val['angle'],$val['left'],$val['top'],$fontColor,$val['fontPath'],$val['text']);
            }
        }
        //生成图片
        if(!empty($filename)){
            $res = imagejpeg ($imageRes,$filename,90); //保存到本地
            imagedestroy($imageRes);
            if(!$res) return false;
            return $filename;
        }else{
            imagejpeg ($imageRes);     //在浏览器上显示
            imagedestroy($imageRes);
        }
    }

     4.关于字体大小  摘自https://zhidao.baidu.com/question/507382898.html

    共有8个参数,缺一不可:
      (1)$image 这个是画布资源,无需再解释;
      (2)$size,官方文档的解释是,字体大小,其长度单位依赖于GD库的版本,对于GD1来说是像素,对于GD2来说是磅(point)。现在一般都是GD2了,那么这个磅究竟是什么意思呢?这涉及到字体设计的基本知识。
      操作位图时,以像素位单位最精确合理,那么使用GD2库的时候,如何绘制大小为20像素的字呢?也就是多少磅才能等于20个像素呢?这必须通过分辨率才能计算出来,而问题是位图本身并没有分辨率的概念。
      现在把问题返回来,如果给定$size=20磅,那么imageTtfText()绘制完成时,究竟会占用多少像素。无论如何,imageTtfText()最终还是要把文字绘制落实到具体的位图像素上。
      这个问题确实非常棘手,此函数内部必然会使用某个分辨率PPI来计算被渲染的像素区域。而GD2库却没有提供任何让用户设置或者读取这个分辨率的方法。那么,我们只能动手测试了。使用不同的磅值绘制文字,然后测量文字占据的像素,通过公式:
      PPI = (72*像素数)/磅值。实验得出的结论是:
      [plain] view plaincopyprint?
      1磅==>4像素, PPI=288
      2磅==>5像素, PPI=180
      3磅==>7像素, PPI=168
      4磅==>8像素, PPI=144
      5磅==>9像素, PPI=129.6
      6磅==>10像素, PPI=120
      7磅==>11像素, PPI=113.14285714286
      8磅==>12像素, PPI=108
      9磅==>14像素, PPI=112
      10磅==>15像素, PPI=108
      11磅==>16像素, PPI=104.72727272727
      12磅==>17像素, PPI=102
      13磅==>18像素, PPI=99.692307692308
      14磅==>19像素, PPI=97.714285714286
      15磅==>21像素, PPI=100.8
      16磅==>22像素, PPI=99
      17磅==>23像素, PPI=97.411764705882
      18磅==>25像素, PPI=100
      19磅==>26像素, PPI=98.526315789474
      20磅==>27像素, PPI=97.2
      21磅==>28像素, PPI=96
      22磅==>29像素, PPI=94.909090909091
      23磅==>30像素, PPI=93.913043478261
      24磅==>32像素, PPI=96
      25磅==>33像素, PPI=95.04
      26磅==>34像素, PPI=94.153846153846
      27磅==>35像素, PPI=93.333333333333
      28磅==>36像素, PPI=92.571428571429
      29磅==>38像素, PPI=94.344827586207
      30磅==>39像素, PPI=93.6
      31磅==>40像素, PPI=92.903225806452
      32磅==>41像素, PPI=92.25
      33磅==>43像素, PPI=93.818181818182
      34磅==>44像素, PPI=93.176470588235
      35磅==>46像素, PPI=94.628571428571
      36磅==>47像素, PPI=94
      37磅==>48像素, PPI=93.405405405405
      38磅==>48像素, PPI=90.947368421053
      39磅==>50像素, PPI=92.307692307692
      40磅==>51像素, PPI=91.8
      41磅==>52像素, PPI=91.317073170732
      42磅==>53像素, PPI=90.857142857143
      43磅==>55像素, PPI=92.093023255814
      44磅==>56像素, PPI=91.636363636364
      45磅==>57像素, PPI=91.2
      46磅==>58像素, PPI=90.782608695652
      47磅==>60像素, PPI=91.914893617021
      48磅==>62像素, PPI=93
      49磅==>63像素, PPI=92.571428571429
      50磅==>63像素, PPI=90.72
      51磅==>64像素, PPI=90.352941176471
      52磅==>67像素, PPI=92.769230769231
      53磅==>68像素, PPI=92.377358490566
      54磅==>69像素, PPI=92
      55磅==>70像素, PPI=91.636363636364
      56磅==>71像素, PPI=91.285714285714
      57磅==>72像素, PPI=90.947368421053
      58磅==>74像素, PPI=91.862068965517
      59磅==>75像素, PPI=91.525423728814
      60磅==>76像素, PPI=91.2
      61磅==>77像素, PPI=90.885245901639
      62磅==>78像素, PPI=90.58064516129
      63磅==>79像素, PPI=90.285714285714
      64磅==>81像素, PPI=91.125
      65磅==>83像素, PPI=91.938461538462
      66磅==>84像素, PPI=91.636363636364
      67磅==>85像素, PPI=91.34328358209
      68磅==>86像素, PPI=91.058823529412
      69磅==>86像素, PPI=89.739130434783
      70磅==>88像素, PPI=90.514285714286
      71磅==>90像素, PPI=91.267605633803
      72磅==>91像素, PPI=91
      73磅==>92像素, PPI=90.739726027397
      74磅==>93像素, PPI=90.486486486486

    可见当大于46磅时,PPI稳定在90,而小于46磅时,PPI一直在微变。
      所以,如果你想绘制20个像素大小的字体,那么必须设置$size参数为:14.5磅。
      另外需要注意的是,$size并不完全对应字体的显示大小,因为同样的$size,不同的字符占据的空间并不是一样的。例如,汉字“国”的宽度会比数字1的宽度大得多,对于标点符号,则更是这样,半角和全角符号也不同。
      总之,使用imageTtfText()不可能精确控制到像素级别,只能大概。这也算是矢量字体的一个小缺陷。

    (4)(5)$x,$y 被绘制字符串的第一个字符的基线点。单位是像素。这里涉及到字体设计的基本知识--基线。这个点绝对不是左上角,(这里要注意)而具体是什么取决于所使用的字体是如何设计的。对于宋体、楷体、黑体等常见的字体中的汉字,这个点大概位于字体的左下部分;而对于英文字母和标点符号,则各不相同。

    5.以为可以成功了,

    字体文件是windows下的font文件下复制的,结果字体不识别,一顿正方形是啥意思。。。码云上搜的成功案例的字体文件使用,嗯 这下可以了

    目录

    1.h5生成海报

    2.本以为大功告成 结果部分安卓手机在这里不执行

    3.直接后台生成

     4.关于字体大小  摘自https://zhidao.baidu.com/question/507382898.html

    5.以为可以成功了,

     

     

    展开全文
  • 微信小程序生成海报

    2020-02-29 06:30:18
    微信小程序生成海报,以及自定义生成海报的内容,然后生成图片保存 微信小程序生成海报,以及自定义生成海报的内容,然后生成图片保存
  • 异步生成海报

    2020-12-26 06:03:41
    <div><p>有些场景可能需要发起ajax请求后才能获取生成海报的数据,需要引入或者配置那些操作。</p><p>该提问来源于开源项目:chuyun/taro-plugin-canvas</p></div>
  • 忙着忙着老大说要生成海报,有个活动要给每个用户来个分享图。想法PS 批处理?脚本? 能甩出去的活都甩出去,机智如我啊python 处理图像(PIL)。这么坑的想法,当然不是我想的了。虽然我实现了写个页面调用之前生成长...

    我最近没有摸鱼,一直都在工作。只不过目前需要爬一点数据 python 做的,之后看机会分享一下。

    忙着忙着老大说要生成海报,有个活动要给每个用户来个分享图。

    想法

    PS 批处理?脚本? 能甩出去的活都甩出去,机智如我啊

    python 处理图像(PIL)。这么坑的想法,当然不是我想的了。虽然我实现了

    写个页面调用之前生成长截图的服务。之前有个为了方便分享微信,做了生成长截图的服务。写个新的页面用一下即可。

    我堂堂前端er,怎么能一直用别的工具呢?我的锤子呢?

    ps处理

    这个方案,经过我调研行不通。(也有可能是我菜)

    对于批量打码,统一操作这类的还可以。

    对于需要对应名字之类的比较无力

    python

    老大说 python。py 使用 PIL 库 写起来还蛮简单的。

    py 使用这段时间以来就是感觉这个编码格式极其难受。有没有大佬解救我一下。

    根据不同的类型输出数据

    txt 使用字体,输出到对应位置

    image 图片,覆盖输出到对应位置。mask=img要注意针对 png 来使用

    qrcode 生成对应二维码

    通过上面的类型,来增加我们代码的扩展性。

    代码

    # -*- coding: utf-8 -*-

    from PIL import Image, ImageDraw, ImageFont

    import qrcode

    import time;

    import re

    def AddMoney(data):

    bg = Image.new('RGBA', (data['width'], data['height']))

    for item in data['list']:

    print(item)

    if item['type'] == 'qrcode':

    qr_pil_obj = qrcode.make(item['url'], border=0).resize((item['width'], item['height']), Image.ANTIALIAS)

    bg.paste(qr_pil_obj,(item['x'],item['y']))

    elif item['type'] == 'image':

    extname = re.search( r'(jpg|png|jpeg)$', item['url']).group()

    # 加载图片

    img = Image.open(item['url'])

    # 缩放

    if (item['width']!= '' and item['height'] != ''):

    img.resize((item['width'], item['height']), Image.ANTIALIAS)

    if extname == 'png':

    bg.paste(img,(item['x'],item['y']), mask=img)

    else:

    bg.paste(img,(item['x'],item['y']))

    elif item['type'] == 'text':

    draw = ImageDraw.Draw(bg)

    ttfront = ImageFont.truetype(item['ttfrontUrl'],item['ttfrontSize'])

    draw.text((item['x'],item['y']),unicode(item['txt'],"UTF-8"), fill=(0,0,0), font=ttfront)

    else:

    print('------------------------------')

    bg.save(data['outputName'])

    data = {

    'width': 750,

    'height': 1334,

    'outputName': './out-%s.png' % (str(time.time())),

    'list':[{"type":"image","url":"./avatar.jpg","x":10,"y":360,"width":750,"height":1334},{"type":"image","url":"./bg.png","x":0,"y":0,"width":750,"height":750},{"type":"qrcode","url":"https://www.lilnong.top","x":0,"y":0,"width":120,"height":120},{"type":"text","txt":"你这个死宅说话","x":140,"y":560,"ttfrontUrl":"./abc.ttf","ttfrontSize":55},{"type":"text","txt":"还挺搞笑的","x":160,"y":630,"ttfrontUrl":"./abc.ttf","ttfrontSize":55}]

    }

    AddMoney(data)

    长截图

    这个也是极好,是之前一个 Node 的服务。省时省力。网上查也不少

    前端技术处理

    我堂堂前端,怎么也得露一手吧。

    基于上面的页面已经成功。我们想一下我们需要干什么?把 html 转成 canvas,然后 canvas.toBlob,然后 download 美滋滋。

    html2canvas 这是一个库,既然已经有写好的了,我们就不费神了。(最难的一步。。。)

    拿到 cavnas 调用 API, canvas.toBlob。

    下载。这个就比较简单了,之前我写过 前端培训-初级阶段-场景实战(2019-06-06)-下载文件&下载进度

    微信公众号

    各种忘记发。补上补上

    结语

    py 写代码是真的短。

    前端处理需要注意跨域、URL空格等问题。

    展开全文
  • 忙着忙着老大说要生成海报,有个活动要给每个用户来个分享图。想法PS 批处理?脚本?能甩出去的活都甩出去,机智如我啊python 处理图像(PIL)。这么坑的想法,当然不是我想的了。虽然我实现了写个页面调用之前生成长...

    我最近没有摸鱼,一直都在工作

    。只不过目前需要爬一点数据python

    做的,之后看机会分享一下。

    忙着忙着老大说要生成海报,有个活动要给每个用户来个分享图。

    想法

    PS 批处理?脚本?能甩出去的活都甩出去

    ,机智如我啊

    python 处理图像(PIL)。这么坑的想法,当然不是我想的了。虽然我实现了

    写个页面调用之前生成长截图的服务。之前有个为了方便分享微信,做了生成长截图的服务。写个新的页面用一下即可。

    我堂堂前端er

    ,怎么能一直用别的 工具 呢?我的锤子呢?

    ps处理

    这个方案,经过我调研行不通

    。(也有可能是我菜)

    对于批量打码,统一操作这类的还可以。

    对于需要对应名字之类的比较无力

    python

    老大说 python。py

    使用PIL

    库 写起来还蛮简单的。

    py

    使用这段时间以来就是感觉这个编码格式极其难受

    。有没有大佬解救我一下。

    根据不同的类型输出数据

    txt 使用字体,输出到对应位置

    image 图片,覆盖输出到对应位置。mask=img

    要注意针对png

    来使用

    qrcode 生成对应二维码

    通过上面的类型,来增加我们代码的扩展性。

    代码

    # -*- coding: utf-8 -*-

    from PIL import Image, ImageDraw, ImageFont

    import qrcode

    import time;

    import re

    def AddMoney(data):

    bg = Image.new('RGBA', (data['width'], data['height']))

    for item in data['list']:

    print(item)

    if item['type'] == 'qrcode':

    qr_pil_obj = qrcode.make(item['url'], border=0).resize((item['width'], item['height']), Image.ANTIALIAS)

    bg.paste(qr_pil_obj,(item['x'],item['y']))

    elif item['type'] == 'image':

    extname = re.search( r'(jpg|png|jpeg)$', item['url']).group()

    # 加载图片

    img = Image.open(item['url'])

    # 缩放

    if (item['width']!= '' and item['height'] != ''):

    img.resize((item['width'], item['height']), Image.ANTIALIAS)

    if extname == 'png':

    bg.paste(img,(item['x'],item['y']), mask=img)

    else:

    bg.paste(img,(item['x'],item['y']))

    elif item['type'] == 'text':

    draw = ImageDraw.Draw(bg)

    ttfront = ImageFont.truetype(item['ttfrontUrl'],item['ttfrontSize'])

    draw.text((item['x'],item['y']),unicode(item['txt'],"UTF-8"), fill=(0,0,0), font=ttfront)

    else:

    print('------------------------------')

    bg.save(data['outputName'])

    data = {

    'width': 750,

    'height': 1334,

    'outputName': './out-%s.png' % (str(time.time())),

    'list':[{"type":"image","url":"./avatar.jpg","x":10,"y":360,"width":750,"height":1334},{"type":"image","url":"./bg.png","x":0,"y":0,"width":750,"height":750},{"type":"qrcode","url":"https://www.lilnong.top","x":0,"y":0,"width":120,"height":120},{"type":"text","txt":"你这个死宅说话","x":140,"y":560,"ttfrontUrl":"./abc.ttf","ttfrontSize":55},{"type":"text","txt":"还挺搞笑的","x":160,"y":630,"ttfrontUrl":"./abc.ttf","ttfrontSize":55}]

    }

    AddMoney(data)

    长截图

    这个也是极好,是之前一个Node

    的服务。省时省力。网上查也不少

    前端技术处理

    我堂堂前端,怎么也得露一手吧。

    基于上面的页面已经成功。我们想一下我们需要干什么?把html

    转成canvas

    ,然后canvas.toBlob

    ,然后download

    美滋滋。

    html2canvas

    这是一个库

    ,既然已经有写好的了,我们就不费神了。(最难的一步。。。)

    拿到cavnas

    调用API

    ,canvas.toBlob

    结语

    py

    写代码是真的短。

    前端处理需要注意跨域

    、URL空格

    等问题。

    展开全文
  • canvas生成海报

    2020-09-23 10:47:26
    需求: 提供一个模板图片,商家输入自己的店铺名,即可生成一张海报。 实现: 使用canvas 画出模板,获取 input 框的内容,再将其添加到指定位置,下载保存。...点击生成海报</button> <button
  • 该demo主要用于微信小程序生成海报功能,简单快捷,容易维护等
  • 主要介绍了JavaScript基于用户照片姓名生成海报,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 首先申请权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE...生成海报 ** * 生成海...
  • uniapp 生成海报图片base64转换 (微信头像贴在海报上需要base64转换)import { pathToBase64, base64ToPath } from "路径" base64ToPath(res.data.data.poster) .then(path => {}) .catch(error => { ...
  • 生成海报图和二维码, 如果是vue的话,先下载两个插件QRCode和html2canvas html //海报html元素放这个标签内 <div id="posterHtml" v-show="true"></div> <!-- 海报图 --> <div class=...
  • TP5生成海报源码

    2019-10-30 12:07:47
    PHP生成海报 php生成海报,包括背景图片和小程序二维码、文字、用户头像等相互合并。 php代码示例: //海报生成 public function poster($adminList){ $adminList=json_decode($adminList,true); ...
  • poster 是后端生成海报图片的一种简单方式,其适用于微信小程序海报分享,保存到相册后可以分享到朋友圈。
  • thinkphp生成海报 Grafika

    2020-08-20 11:28:44
    使用的是Grafika组件,下载及手册 <?...namespace app\api\controller... * 生成海报 * @param $openid 推荐者用户id * @param $qrcodeUrl 二位码将要跳转的链接 */ public function create($openid='', $qrcodeUrl
  • 小程序canvas生成海报

    千次阅读 2020-09-29 16:11:25
    小程序canvas生成海报先看看效果图 以下↓使用场景前提wxmljsdrawCanvas.js在Canvas.js引入drawCanvas.js希望大家能够用到! 如果文章中有出现纰漏、错误之处,还请看到的小伙伴多多指教,先行谢过 先看看效果图 ...
  • vue canvas 生成海报

    千次阅读 2019-07-27 11:26:50
    canvas 生成海报 1.创建canvas getxjb() { this.$nextTick(() => { this.mycan = document.getElementById("myCanvas"); var ctx = this.mycan.getContext("2d"); var img = new Image...
  • uniapp 微信小程序 生成海报 记一次,uniapp 微信小程序 生成海报的解决方案,采用的是 painter 这个插件 这是官方地址 painter 这是参考的大佬文章 链接 生成代码的网站 链接
  • <?.../** * @Description * @Params * @Return * @DateTime 2019/11/4 15:58 * @Auth Windows PHPstorm */ ... * getbgqrcode() 根据... * index() 调用生成海报的方法,初始化 海报图片,二维码等图片 * ge...
  • canvas生成海报点击下载 ` canvas生成海报点击下载 下载 */ var c = document.getElementById(“canvas”); var ctx = c.getContext(“2d”); // 背景图 ctx.fillStyle = “#eee”; ctx.fillRect(0, 0,...
  • 小程序之生成海报

    2019-08-30 18:29:36
    小程序之生成海报 废话不说,直接上干货~ //生成海报 createposter: function () { let that = this; that.createNewImg(); // 执行绘图 that.setData({actionSheetHidden:true}); if (that.data.swiperImgs...
  • 基于canvas生成海报

    2018-10-12 12:59:42
    基于此,我写了一个基于canvas生成海报的js库。github地址 效果图 使用说明 最简单的使用配置: // html &lt;div class="poster"&gt;&lt;/div&gt; // js poster.init({ banner: './...
  • 关于小程序生成海报

    2020-05-21 11:03:19
    关于小程序生成海报并保存到本地相册 生成图片的过程 toSetImage(obj,width,height,imgUrl,codeImg,text) { //obj是页面的this //with,height指的是canvas的宽高 //imageUrl 指的的海报的图片 //codeImg 指...
  • 微信小程序demo示例,根据内容生成海报图片,一共有10个源码示例。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,024
精华内容 809
关键字:

生成海报