小工具:占位图片生成v1.0

该工具支持生成自定义尺寸图片,可以配置图片中自定义文字和图片背景颜色。
252阅读 · 2020-4-17 16:06发布

工具由python编写,后端使用django框架,前端使用layui框架。使用了SourceHanSans-Normal字体、PIL图像库。

页面预览

实现步骤

初始化项目

  • 新建或打开已有django项目。
  • 新建tools应用:点击PyCharm中Tools-Run manage.py Task,输入以下内容:
    startapp tools
    
  • settings.py中添加tools应用:编辑settings.py文件,在INSTALL_APP中增加tools应用路径。示例:
    INSTALLED_APPS = [
          'apps.tools.apps.ToolsConfig',
      ]
    
  • urls.py中添加tools应用的路径:tools应用使用自己的urls文件,在主urls文件中指定tools的urls.py。示例:
    #django项目中的urls.py
      from django.conf.urls import url,include
      urlpatterns = [
          url(r'^tools/', include(('apps.tools.urls',"tools"),namespace='tools')),
      ]
    

后端配置

  • 将字体文件SourceHanSans-Normal.otf拷贝到static/font/中。(可以自行选择任意字体文件放入)
  • 编写views.py:编写占位图片小工具的后端逻辑。示例:

    import os
    
      from PIL import Image,ImageDraw, ImageFont
      from django.shortcuts import render
      from django.views.generic.base import View
      from django.conf import settings
    
      class Placeholder(View):
    
          """给图片添加文字"""
          def pic_text(self,p_text, image_url, colour, image_size):
              image_path = os.path.join(settings.BASE_DIR, "media/" + image_url)
              text_position = (image_size[0]/3,image_size[1]/3)
              colour = colour[:5]
              size = int(image_size[0]/len(p_text))
    
              #设置字体和大小
              fontpath = os.path.join(settings.BASE_DIR, "static/font/SourceHanSans-Normal.otf")
              font = ImageFont.truetype(fontpath,size)
    
              image = Image.open(image_path)
              draw = ImageDraw.Draw(image)
    
              # 文字居中计算
              sum_width = 0
              sum_height = 0
              for char in p_text:
                  width, height = draw.textsize(char, font)
                  sum_width += width
                  sum_height = height
    
              # 在图片上生成文字
              draw.text(((image_size[0] - sum_width) / 2, (image_size[1] - sum_height) / 2), p_text, colour,font=font)
    
              # 保存
              image.save(image_path)
    
          def get_pic(self,size_xy,colour,p_text):
    
              #图片名称和路径
              image_url = "placeholder/{p_text}.png".format(p_text=p_text)
              image_path = os.path.join(settings.BASE_DIR, "media/"+image_url)
    
              #生成纯色图片
              newImg = Image.new("RGB", size_xy, colour)
              newImg.save(image_path, "PNG")
    
              return image_url
    
          def post(self, request, *args, **kwargs):
              size = str(request.POST.get("size"))
              size_xy = (int(size.split('x')[0]),int(size.split('x')[1]))
              colour = request.POST.get("colour")
              p_text = request.POST.get("p_text")
    
              #生成纯色图片
              image_url = self.get_pic(size_xy,colour,p_text)
    
              #调用添加文字方法
              self.pic_text(p_text,image_url,colour,size_xy)
    
              return render(request, 'placeholder.html', {
                  'image_url': image_url,
                  'image_uri': image_url.split('/')[1],
                  'size': size,
                  'colour': colour,
                  'p_text': p_text
              })
    
          def get(self, request, *args, **kwargs):
              return render(request, 'placeholder.html')
    
  • 添加tools的url路径:在tools应用的urls.py中添加路径。示例:

    from django.conf.urls import url
      from apps.tools.views import Placeholder
    
      urlpatterns = [
          url(r'^placeholder/$', Placeholder.as_view(),name="placeholder"),
      ]
    

前端配置

  • 将相关的layui文件(css、font、js)放进static中对应位置。
  • 新建前端页面placeholder.html:示例:

    <!--placeholder.html-->
      <!DOCTYPE html>
      {% load staticfiles %}
      <html>
      <head>
        <meta charset="utf-8">
        <title>Layui</title>
        <meta name="renderer" content="webkit">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
        <link rel="stylesheet" href="{% static 'css/layui.css' %}"  media="all">
      </head>
      <body>
    
      <!--颜色选择器-->
      <div style="margin-left: 30px;">
          <form class="layui-form" action="{% url 'tools:placeholder' %}" style="padding-top: 25px" method="post">
              <div class="layui-form-item">
                  图片尺寸:           <input name="size" type="text" value="{% if size %}{{ size }}{% else %}741x565{% endif %}" style="width: 100px;" placeholder="741x565">
                  (长宽用x分割,示例:741x565)
              </div>
    
              <div class="layui-form-item">
                  显示文字:           <input name="p_text"  type="p_text" value="{% if p_text %}{{ p_text }}{% else %}图片中显示的文字{% endif %}" placeholder="图片中显示的文字">
              </div>
    
              <div class="layui-form-item">
                  <div class="layui-inline" style="left: -131px;">
                      <div id="test-form"></div>
                  </div>
    
                  <div class="layui-input-inline" style="width: 120px;right: -38px;">
                      <input name="colour" type="text" value="{% if colour %}{{ colour }}{% else %}#c8d3dc{% endif %}" placeholder="选择背景颜色" class="layui-input" id="test-form-input">
                  </div>
              </div>
              {% csrf_token %}
              <button>生成图片</button>
          </form>
          <div style="padding: 20px">
              {% if image_url %}图片链接(右键图片另存为即可):<br><a style="text-decoration:underline;color: #0000FF" href="{{ MEDIA_URL }}{{ image_url }}" target="_blank">{{ image_uri }}</a>{% endif %}
          </div>
      </div>
    
      <script src="{% static 'js/layui.js' %}" charset="utf-8"></script>
      <script>
      layui.use('colorpicker', function(){
        var $ = layui.$
        ,colorpicker = layui.colorpicker;
        //常规使用
        colorpicker.render({
          elem: '#test1' //绑定元素
          ,change: function(color){ //颜色改变的回调
            layer.tips('选择了:'+ color, this.elem, {
              tips: 1
            });
          }
        });
    
        //初始色值
        colorpicker.render({
          elem: '#test2'
          ,color: '#2ec770' //设置默认色
          ,done: function(color){
            layer.tips('选择了:'+ color, this.elem);
          }
        });
    
        //表单赋值
        colorpicker.render({
          elem: '#test-form'
          ,color: '{% if colour %}{{ colour}}{% else %}#c8d3dc{% endif %}'
          ,done: function(color){
            $('#test-form-input').val(color);
          }
        });
    
        //RGB 、RGBA
        colorpicker.render({
          elem: '#test3'
          ,color: 'rgb(68,66,66)'
          ,format: 'rgb' //默认为 hex
        });
        colorpicker.render({
          elem: '#test4'
          ,color: 'rgba(68,66,66,0.5)'
          ,format: 'rgb'
          ,alpha: true //开启透明度滑块
        });
    
        //开启透明度
        colorpicker.render({
          elem: '#test5'
          ,color: '#009688' //hex
          ,alpha: true //开启透明度
          ,format: 'rgb'
        });
        colorpicker.render({
          elem: '#test6'
          ,color: 'rgb(0,150,136,0.6)' //rgba
          ,alpha: true
          ,format: 'rgb'
        });
        colorpicker.render({ //无初始色值时
          elem: '#test7'
          ,alpha: true
          ,format: 'rgb'
        });
    
        //预定义颜色项
        colorpicker.render({
          elem: '#test8'
          ,color: '#c71585'
          ,predefine: true // 开启预定义颜色
        });
        colorpicker.render({
          elem: '#test9'
          ,color: '#9d8a0e'
          ,predefine: true // 开启预定义颜色
          ,colors: ['#ff8c00','#00ced1','#9d8a0e'] //自定义预定义颜色项
        });
    
        //开启全功能
        colorpicker.render({
          elem: '#test-all'
          ,color: 'rgba(7, 155, 140, 1)'
          ,format: 'rgb'
          ,predefine: true
          ,alpha: true
          ,done: function(color){
            $('#test-all-input').val(color); //向隐藏域赋值
            layer.tips('给指定隐藏域设置了颜色值:'+ color, this.elem);
    
            color || this.change(color); //清空时执行 change
          }
          ,change: function(color){
            //给当前页面头部和左侧设置主题色
            $('.header-demo,.layui-side .layui-nav').css('background-color', color);
          }
        });
    
        //设定颜色框尺寸
        colorpicker.render({
          elem: '#test10'
          ,size: 'lg' //大号下拉框
        });
        colorpicker.render({
          elem: '#test11'
          //,size: 'sm' //默认 sm
        });
        colorpicker.render({
          elem: '#test12'
          ,size: 'xs' //mini下拉框
        });
      });
      </script>
    
      </body>
      </html>
    

启动项目

使用PyCharm,点击Run-Run。访问下方Run页面出现的地址即可。

总结

工具还有很多不足的地方,希望有空时能完善该功能!