Some attempts to automatically generate images in front-end development and image generation development attempts

Source: Internet
Author: User

Some attempts to automatically generate images in front-end development and image generation development attempts

Image processing takes a lot of time in front-end development and is very tiring. In this article, we will not discuss how to improve the efficiency of the cut graph. We will discuss another question: how to deal with some simple graphics in the design draft. I don't know if you have ever encountered this kind of annoyance: "The designer gives you a simple image in the exquisite PSD, that is, a graph consisting of polygon, circles, and lines. This image cannot be implemented or implemented using css3. However, to be compatible with Some browsers, css3 cannot be implemented and only supports graph cutting. Okay, you have quickly finished cutting and referenced it in the style. But it didn't take long before the requirement was to change the color of the image. This is the PSD that you have deleted from the exported image, and you have to pull the image out again in the design draft ". Or in a more abnormal version, your project supports skin replacement, and the image will have different colors under different skins. You need to export the image to several different color versions. If the color is modified later, you need to modify and export the image one by one. If the psd used to export the image is gone, you have to deduct it from the design draft, after one modification, export the image. If you do not pay attention to it, the size and position of the two images may be different, causing dislocation. If you haven't met any of the above situations, You Should Be lucky, and I have met both of them. When I make these tedious changes, I am always running on ten millions of alpaca.

Is there no way to simplify this operation? Can I modify the image by modifying only a few parameters like modifying css? To accomplish this goal, we must do two things: 1. How to describe these simple images with text 2. How to convert a simple image described with text to an image. It is easy to do the first job. It can be done with svg. But how can we implement the second job?

How to convert svg to images

Because the images we describe using SVG generally need to be integrated with other elements on the page, we must convert our SVG images to support transparent png format. How can we convert svg to png? Searching on the Internet for a long time has not been particularly ideal. The solution is basically two routines. You can either call phantom through the command line (or through canvas, but canvas is based on phantom ), you can call GraphicsMagick (gm) through a command line ). The two software are both powerful in size, and the installation is very complicated, especially in windows, and the support for svg is not very friendly. Phantom needs to use canvas to convert SVG to png. However, gm needs to install a third-party library to process svg, and the processed image is not very effective. The transparent part of my test image is filled with white, if transparency is not handled well, other features will not be tested. It is estimated that they will not be there.

So far, the research has entered a dead end and failed to continue. It was not until one of the other projects investigated the technical feasibility of a small function. At that time, I wanted to make a small tool to cut a very long image and upload it so as to facilitate lazyload on the mobile phone. because we know that nodejs is a waste of processing images, it is interesting to use java instead of nodejs. Thanks to the good java ecosystem, it is easy to complete the functions I want. After that, I couldn't help wondering why I didn't use java to try this function? Search for "java svg to png" on Google and immediately get the result. Apache has a library named batik dedicated to processing svg. I used to have a good colleague who always said to me, "the most difficult thing to solve is how to convert your problem into a suitable search keyword ". So far, I have a deep understanding.

Batik not only supports SVG very well, but also has very powerful functions. It not only uses DOM APIs to operate SVG documents, it also provides many practical functions such as converting svg to other formats and embedding JavaScript code in svg. One of the official jar packages can be run in the command line to convert svg images to other formats. It is also very easy to use:

java -jar batik-rasterizer.jar foo.svg

This is what we need. So far, the batik-based solution should be the most perfect so far. The jar file can be run without being installed separately, and there is no requirement for the directory structure. You can put the jar and js files in a directory and publish them together with the js Code. Although you also need to install the java Runtime Environment, the installation of the java Runtime Environment is relatively easy, and every computer in the company is installed, so this condition is acceptable.

Export jar files that can run independently

Although the jar file that comes with batik can be run in the command line can meet our requirements, there are still two shortcomings. First, this jar file cannot be run independently. It depends on other jar files in the project. You must store the jar files it depends on in a specific directory structure for running. It seems uncomfortable to put so many files together in disorder. Another unpleasant thing is that the jar file can only specify the svg file to be operated through the command line. It does not support specifying the svg code to be converted through the command line, therefore, you cannot discard an svg string for processing. You must write the string to a temporary file. This is inconvenient to integrate with other build tools, and creating and deleting files in the Code directory may trigger the grunt watch task to cause unnecessary compilation. Based on these two intolerable shortcomings, we cannot use the jar file that comes with it, you need to write a jar file that can run independently and supports setting the svg code to be converted through the command line. The entire function can be easily implemented by combining the information on the Internet. The following is the code implementation:

Package myless. func; import java. io. byteArrayInputStream; import java. io. fileOutputStream; import java. io. inputStream; import java. io. outputStream; import org. apache. batik. transcoder. transcoderInput; import org. apache. batik. transcoder. transcoderOutput; import org. apache. batik. transcoder. image. PNGTranscoder; import org. apache. xerces. impl. dv. util. base64; public class Converter {public static void main (String... args) throws Exception {// to avoid the problem of OSS encoding in ms dos, the parameter is base64 encoded byte [] svg_code = Base64.decode (args [0]); string save_path = new String (Base64.decode (args [1]), "UTF-8"); if (args. length> = 3 & args [2]. toLowerCase (). equals ("-- show-debug") {System. out. println ("svg content: \ n" + new String (svg_code, "UTF-8"); System. out. println ("save path: \ n" + save_path);} InputStream svg_stream = new ByteArrayInputStream (svg_code); OutputStream png_stream = new FileOutputStream (save_path ); transcoderInput input_image = new TranscoderInput (svg_stream); TranscoderOutput output_image = new TranscoderOutput (png_stream); PNGTranscoder transcoder = new PNGTranscoder (); transcoder. transcode (input_image, output_image); svg_stream.close (); png_stream.flush (); png_stream.close ();}}

The export function of eclipse is used to export executable jar files. For detailed operation steps, refer to Baidu's experience.

Integrate the conversion function into less

Once the jar file can be run independently, it is easy to be used by nodejs, because nodejs itself supports calling system commands through command lines. In addition, the command line call function is added after version 0.12.0. Therefore, we can use nodejs to convert SVG images to png images.

  • The nodejs program calculates the jar file path to be called through the path of the current file.
  • Nodejs generates the SVG code to be converted and base64 encoded
  • Nodejs sets the path to save the converted image and base64 encoding
  • Nodejs calls the command line synchronously:
java -jar convert.jar base64-encode-svg base64-encode-save-path

The following code is the implementation of the Conversion Function in grunt-myless. Because the conversion process is time-consuming, in order to improve the overall compilation progress and determine whether to reproduce the conversion logic, only the md5 value of the svg code will change.

/*** @ FileOverview: Convert the SVG code to a png file. * @ param String the path for saving the converted file * @ param String... svg property and svg Code * @ return String save absolute address * @ example * div {* background: svg-to-png ('width = 60px ', 'height = 30px ', 'baseb4-encode = true', <EOF * <! -- Add you svg code here --> * EOF) center no-repeat; *} */var fs = require ('fs '); var path = require ('path'); var crypto = require ('crypto'); var child_proc = require ('child _ Process'); var jarPath = path. join (_ dirname ,'.. /jar/svg-to-png.jar '); module. exports = function (myless, savePath) {'use strict '; var util = myless. util, fileProps, error; var args = []. slice. call (arguments, 1 ). map (function (I) {return I. value;}); var data = util. svg. parseInput. apply (null, args. slice (1); var picPath = util. file. getRefFilePath (savePath, false); var svgCode = util. svg. getSVGCode (data. attrs, data. cont); var contMd5 = crypto. createHash ('md5 '). update (svgCode ). digest ('hex'); // If a png file already exists, check whether the svg content of the generated image has changed. If no change exists, the image will not be regenerated. if (fs. existsSync (picPath) {fileProps = util. file. getFileProps (picPath); if (filePro Ps ["cont-md5"] = contMd5) {util. console. log ('svg-to-png: <green> svg conttent not change, return cached file! </Green> '); return picPath;} var codeBase64 = new Buffer (svgCode ). toString ('base64'); var pathBase64 = new Buffer (picPath ). toString ('base64'); var command = "java-jar" + jarPath + ''+ codeBase64 +'' + pathBase64; try {util. file. mkFilePath (picPath); child_proc.execSync (command, {encoding: 'utf8'});} catch (e) {error = e;} finally {if (error) {if (fs. existsSync (picPath) {fs. unlinkSync (PicPath);} throw (''+ 'svg-to-png.js: create png file:" '+ savePath. value +' "error! \ N' + 'svg content: '+ svgCode + 'error info:' + error) ;}} util. file. setFileProps (picPath, {"cont-md5": contMd5}); return picPath ;}
Practical Application in projects

This feature is being developed recently in this project to handle IE78 compatibility. In this project, the designer designs the rounded corner and circular background Effects for some areas of the page, and the page has 6 skin sets, and the color of these details will change under different skin settings. In this project, we need to perform compatibility processing on low-end browsers, as shown in the following figure:

The background and border of the Countdown area are the same as the background and border color of the like button, while the background circle on the left side of the title is different from the background circle on the bottom of the prize. Therefore, if there are five sets of different skins, I only need to measure 5 sets of different color data, and then generate images based on these 5 sets of data. Therefore, the following less code is used to complete this function.

/*** @ FileOverview ie9 the following browser-compatible styles. * @ since 2015.07.10 */. mix-circle-pic-bg (@ saveTo, @ color: # c7173d, @ width: 176) {@ r: @ width/2; @ bg-image: svg-to-png (@ saveTo, 'width = @ {width} ', 'height = @ {width }', <EOF <circle cx = "@ {r}" cy = "@ {r}" r = "@ {r}" stroke = "none" fill = "@ {color} "/> EOF ); * background-image: tbcdn-uri (@ bg-image); background-image: data-uri (@ bg-image); background-repeat: no-repeat ;}. mix-theme (@ Theme, @ time-rect-color, @ time-border-color, @ prize-title-circle-color, @ prize-item-circle-color) {@ toolbar-circle-color: @ time-rect-color; @ toolbar-shadow-color: @ time-border-color ;. ylb-turntable. @ {theme }{. main. time-card {background-color: transparent ;. time-card-inner {background-color: transparent;} @ bg-image: svg-to-png ('. /img/@effectheme0000-time-card-bg.png ', 'width = 290px', 'height = 169 p X ', <EOF <rect x = "0" y = "3" width = "290" height = "166" rx = "6" ry = "6" fill = "@{ time-border-color} "/> <rect x =" 0 "y =" 0 "width =" 290 "height =" 166 "rx =" 6 "ry =" 6 "fill =" @ {time-rect-color} "/> EOF ); background-image: data-uri (@ bg-image); * background-image: tbcdn-uri (@ bg-image );}. main. toolbar-card {@ bg-image: svg-to-png ('. /img/@effectheme0000-toolbar-bg.png ', 'width = 100px', 'height = 0000px ', <EOF <circle cx = "50" Cy = "54" r = "50" fill = "@ {toolbar-shadow-color}"/> <circle cx = "50" cy = "50" r = "50 "fill =" @ {toolbar-circle-color} "/> EOF ); &: before {display: none;} background: data-uri (@ bg-image) 0 0 no-repeat; * background: tbcdn-uri (@ bg-image) 0 0 no-repeat ;}. footer. prize-arrow-wrap {&: before {display: none! Important ;}. mix-circle-pic-bg ('. /img/@{theme}-prize-title-bg.png ', @ prize-title-circle-color, 28 );}. footer. prize-card {&: before {display: none! Important ;}. mix-circle-pic-bg ('. /img/@{theme}-prize-item-bg.png ', @ prize-item-circle-color, 176 );}}} /*-= topic section = --------------- * // Add t in front of the topic name because the following colors are less and will be automatically converted to the hexadecimal value of the corresponding color if the keyword is less // I have been stuck with this bug for a long time, debugging takes only half a day to discover .. Mix-theme (t-pink, # c21339, # de2e54, # e4214b, # c7173d );. mix-theme (t-blue, #2581d5, # 3da2ff, #2581d5, # 2273bd );. mix-theme (t-green, # 7ea41a, # acd635, #96bc24, #719103 );. mix-theme (t-violet, #9978d5, # bc98ff, #9c7bd9, # 7758ad );. mix-theme (t-red, # cf1e29, # fa3f43, # d6202d, # bf222c );

In general, the running effect is not bad. The image quality is slightly inferior to that of photoshop, but it is still usable.
Click the icon background in different colors generated by code:

Notes
  • Batik supports translucent rgba functions but does not support css3. You need to use the fill-opacity attribute to specify transparency. For example, if you want to specify a translucent fill color for a rect, you cannot set it as follows: "fill = 'rgba (0.5, 0,) '". You need: "fill = '# 000' fill-opacity = '0. 5 '"
  • Color constants in css such as pink and red will be replaced with the corresponding hexadecimal identifier in less. Do not use them when naming variables.
Thanks
  • Thoughts @ Zhang BA and @ Si Yong technical support for java and eclipse operations
References
  • Http://stackoverflow.com/questions/15256112/java-svg-to-jpg-converter
  • Http://stackoverflow.com/questions/8167977/how-to-convert-svg-into-png-on-the-fly
  • Http://thinktibits.blogspot.com/2012/12/Batik-Convert-SVG-PNG-Java-Program-Example.html
  • Http://xmlgraphics.apache.org/batik/tools/rasterizer.html

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.