当前位置:   article > 正文

uni保存canvas图片_中文汉字注音,汉字转拼音,支持图片识别文字,支持结果转图下载,附上小程序核心源码...

uniapp怎么canvas转换成打印机可以识别的字符串

“文字注音”小程序在微信、字节跳动、支付宝、QQ等小程序平台同步上线,微信、头条、抖音、支付宝、QQ中搜索“文字注音”即可获得。

一、功能

汉字转拼音,支持图片识别文字,支持结果转图下载。该款小程序能够轻松将文字注音后输出,无需授权,无需注册,即来即用。你还可以用它来识别图片中的文字后注音,或者随时拍照后识别文字再注音。同时支持注音完成后复制拼音,支持将结果保存成图片下载到手机本地。欢迎扫描下面的各平台得小程序码来尝试一下。

5e3696e097ff57164e6b5fdc1d878706.png

9a6c9431ae98c370b005ea4e8024bedd.png

二、平台小程序码

359e39b474ea1ab704ebf74de91a1fc1.png

三、核心源码:

原文链接:

中文汉字注音,汉字转拼音,支持图片识别文字,支持结果转图下载,附上小程序核心源码 | 文思齐远 | 分享你我他​www.i847.cn
ca586ab0b2906c7d9a9e19b49a85b9c3.png
  1. <template>
  2. <view class="content" style="width:100%">
  3. <view class="uni-textarea" style="width: 95%;margin: 0 auto;">
  4. <textarea v-if="status==0" :value="value" @input="valueChange" :style="{'height':textareaHeight+'px'}"
  5. placeholder="请在这里输入或者粘贴文字,支持上传图片自动识别文字,支持中文注音。" maxlength="-1" adjust-position="{{keyUp}}"
  6. @focus="focusTextarea" @blur="blurTextarea" />
  7. <view v-if="status==1" :style="{'height':resultHeight+'px','width': '100%','overflow-y': 'scroll'}" id="result">
  8. <view class="uni-row" style="padding: 9px 2%;font-size: 14px;text-align: center;">
  9. <view v-for="(item,i) in list" v-if="item.pinyin!='enter'" v-bind:key="i" class="uni-flex uni-column" style="float: left;margin: 3px;">
  10. <view class="flex-item" style="min-width: 1px;">{{item.pinyin}}</view>
  11. <view class="flex-item">{{item.value}}</view>
  12. </view>
  13. <view v-else style="clear: both;"></view>
  14. </view>
  15. </view>
  16. </view>
  17. <view style="position: fixed;bottom: 15px;width: 100%;">
  18. <view v-if="status==0" style="width: 92%;margin: 0 auto;margin-bottom: 10px;font-size: 16px;color: #6495ED;">
  19. <text style="cursor: pointer;" @tap="fromImg('album')">图片识别</text>
  20. <text style="cursor: pointer;margin-left: 10px;" @tap="fromImg('camera')">拍照识别</text>
  21. <text style="font-size: 12px;color: #B2B2B2;">(上传图片不宜过大)</text>
  22. </view>
  23. <view class="uni-flex uni-row" style="width: 92%;margin: 0 auto;">
  24. <view v-if="status==0" class="flex-item" style="width: 70%;">
  25. <button type="primary" style="width: 99%;float: left;" @tap="zhuyin()">注音</button>
  26. </view>
  27. <view v-if="status==1" class="flex-item" style="width: 35%;">
  28. <button type="primary" style="width: 99%;float: left;" @tap="copy()">复制</button>
  29. </view>
  30. <view v-if="status==1" class="flex-item" style="width: 35%;">
  31. <button type="primary" style="width: 99%;float: right;" :loading="down" :disabled="down" @tap="save()">下载</button>
  32. </view>
  33. <view class="flex-item" style="width: 30%;">
  34. <button type="default" style="width: 90%;float: right;" @tap="reset()">清空</button>
  35. </view>
  36. <view style="clear: both;"></view>
  37. </view>
  38. </view>
  39. <canvas canvas-id="canvas" :style="{'z-index': '-1','position': 'absolute','top': '0px','left': '0px','width': canvasWidth + 'px','height': canvasHeight + 'px'}" v-if="showCanvas"></canvas>
  40. </view>
  41. </template>
  42. <script>
  43. var bopomofo = require('../../static/bopomofo.min.js');
  44. export default {
  45. data() {
  46. return {
  47. value: '',
  48. status: 0,
  49. list:[] ,
  50. textareaHeight: 0,
  51. resultHeight: 0,
  52. baiduToken: {},
  53. showCanvas: false,
  54. down:false,
  55. canvasWidth:0,
  56. canvasHeight:0,
  57. pixelRatio :1,
  58. textareaStaticHeight:0,
  59. canvasStaticHeight:0,
  60. keyUp:false,
  61. }
  62. },
  63. onLoad() {
  64. this.reset();
  65. },
  66. onReady(){
  67. var _that = this;
  68. uni.getSystemInfo({
  69. success: function (res) {
  70. var windowHeight = res.windowHeight;
  71. _that.textareaHeight = windowHeight - 115;
  72. _that.textareaStaticHeight = windowHeight - 115;
  73. _that.resultHeight = windowHeight - 70;
  74. _that.canvasWidth = res.windowWidth;
  75. _that.canvasHeight = res.windowHeight * 10;
  76. _that.canvasStaticHeight = res.windowHeight * 10;
  77. _that.pixelRatio = res.pixelRatio;
  78. }
  79. });
  80. uni.getStorage({
  81. key: 'baiduToken',
  82. success: function (res) {
  83. _that.baiduToken = res.data;
  84. var now = new Date().getTime();
  85. if(!_that.baiduToken || now > _that.baiduToken.expires){
  86. _that.getBaiduToken();
  87. }
  88. },
  89. fail:function(e) {
  90. _that.getBaiduToken();
  91. }
  92. });
  93. uni.showShareMenu();
  94. },
  95. methods: {
  96. focusTextarea:function(e){
  97. this.textareaHeight = 100;
  98. },
  99. blurTextarea:function(e){
  100. this.textareaHeight = this.textareaStaticHeight;
  101. },
  102. save:function(){
  103. var _that = this;
  104. _that.down = true;
  105. //先设置canvas得高度
  106. _that.canvasHeight = _that.canvasStaticHeight;
  107. _that.showCanvas = true;
  108. setTimeout(function(){
  109. var ctx = uni.createCanvasContext("canvas",_that);
  110. ctx.rect(0, 0, _that.canvasWidth, _that.canvasHeight);
  111. ctx.setFillStyle('white');
  112. ctx.fill();
  113. ctx.setFillStyle('black');
  114. // 字体大小
  115. ctx.setFontSize(14);
  116. var fontHeight = 14;
  117. // 宽度
  118. var width = _that.canvasWidth;
  119. // 横向间隔
  120. var transverse = 9;
  121. // 纵向小间隔
  122. var portraitSmall = 4;
  123. // 纵向大间隔
  124. var portraitBig = 7;
  125. // 外间距
  126. var padding = 20;
  127. // 横向距离累计
  128. var transverseCumulative = padding;
  129. // 纵向距离累计
  130. var portraitCumulative = padding;
  131. var lineHeight = portraitSmall + portraitBig + (fontHeight*2);
  132. for(var i=0;i<_that.list.length;i++){
  133. // canvas高度变化
  134. if(i==0){
  135. _that.canvasHeight = portraitCumulative + lineHeight;
  136. setTimeout(function(){},10);
  137. }
  138. var item = _that.list[i];
  139. var metrics = ctx.measureText(item.pinyin);
  140. var tempX = transverseCumulative + transverse + metrics.width;
  141. if(tempX > (width-padding) || item.pinyin=="enter"){
  142. transverseCumulative = padding;
  143. portraitCumulative = portraitCumulative + lineHeight;
  144. _that.canvasHeight = portraitCumulative + lineHeight;
  145. setTimeout(function(){},10);
  146. }
  147. if(item.pinyin!="enter"){
  148. var x1;
  149. if(transverseCumulative==padding){
  150. x1 = transverseCumulative;
  151. }else{
  152. x1 = transverseCumulative + transverse;
  153. }
  154. var y1 = portraitCumulative;
  155. ctx.fillText(item.pinyin, x1, y1);
  156. var x2 = x1;
  157. var y2 = y1 + portraitSmall + fontHeight;
  158. ctx.fillText(item.value,x2, y2);
  159. transverseCumulative = x1 + metrics.width;
  160. }
  161. }
  162. ctx.draw();
  163. setTimeout(function(){
  164. uni.canvasToTempFilePath({
  165. width: _that.canvasWidth,
  166. height: _that.canvasHeight,
  167. destWidth: _that.canvasWidth * _that.pixelRatio,
  168. destHeight: _that.canvasHeight * _that.pixelRatio,
  169. canvasId: 'canvas',
  170. success: function(res) {
  171. uni.saveImageToPhotosAlbum({
  172. filePath: res.tempFilePath,
  173. success:function(){
  174. uni.showToast({
  175. title:"保存成功"
  176. })
  177. },
  178. complete:function(){
  179. _that.showCanvas = false;
  180. _that.down = false;
  181. }
  182. });
  183. },
  184. fail:function(e){
  185. console.log(e);
  186. _that.showCanvas = false;
  187. _that.down = false;
  188. }
  189. })
  190. },100);
  191. },100);
  192. },
  193. getBaiduToken:function(){
  194. var _that = this;
  195. var now = new Date().getTime();
  196. uni.request({
  197. url: 'https://aip.baidubce.com/oauth/2.0/token',
  198. method: 'GET',
  199. data: {
  200. grant_type: 'client_credentials',
  201. client_id: '',
  202. client_secret: '',
  203. },
  204. success: (res) => {
  205. _that.baiduToken = {
  206. access_token:res.data.access_token,
  207. expires:(res.data.expires_in * 1000 + now - 24 * 60 * 60 * 1000)
  208. }
  209. uni.setStorage({
  210. key: 'baiduToken',
  211. data: _that.baiduToken,
  212. success: function () {
  213. }
  214. });
  215. }
  216. });
  217. },
  218. fromImg:function(type){
  219. var _that = this;
  220. uni.chooseImage({
  221. count: 1,
  222. sourceType: [type],
  223. success: function (res) {
  224. uni.getFileSystemManager().readFile({
  225. filePath: res.tempFilePaths[0],
  226. encoding: 'base64',
  227. success: res => {
  228. var base64 = res.data;
  229. uni.showLoading({
  230. title: '上传中...',
  231. mask:true
  232. });
  233. uni.request({
  234. url: 'https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic',
  235. method: 'POST',
  236. header: {
  237. 'Content-Type': 'application/x-www-form-urlencoded'
  238. },
  239. data: {
  240. access_token: _that.baiduToken.access_token,
  241. image: encodeURI(base64),
  242. detect_direction: true
  243. },
  244. success: (res) => {
  245. uni.hideLoading();
  246. if(res.data){
  247. var value = '';
  248. for(var i=0;i<res.data.words_result_num;i++){
  249. value += res.data.words_result[i].words + "n";
  250. }
  251. _that.value = value;
  252. }
  253. }
  254. });
  255. },fail: (e) => {
  256. console.log(e);
  257. }
  258. })
  259. }
  260. });
  261. },
  262. copy:function(){
  263. if(this.list.length>0){
  264. var data = "";
  265. for(var i=0;i<this.list.length;i++){
  266. if(this.list[i].pinyin==" "){
  267. data += this.list[i].value;
  268. }else if(this.list[i].pinyin=="enter"){
  269. data += "n";
  270. }else{
  271. data += this.list[i].pinyin + " ";
  272. }
  273. }
  274. uni.setClipboardData({
  275. data: data,
  276. success: function () {
  277. uni.showToast({
  278. title: '复制成功',
  279. duration: 2000
  280. });
  281. }
  282. });
  283. }
  284. },
  285. zhuyin:function(){
  286. var _that = this;
  287. if(this.value!=''){
  288. // 敏感词过滤
  289. uni.request({
  290. url: 'https://aip.baidubce.com/rest/2.0/solution/v1/text_censor/v2/user_defined',
  291. method: 'POST',
  292. header: {
  293. 'Content-Type': 'application/x-www-form-urlencoded'
  294. },
  295. data: {
  296. access_token: _that.baiduToken.access_token,
  297. text: _that.value,
  298. },
  299. success: (res) => {
  300. if(res.data.conclusionType == 1){
  301. _that.zhuyinDo();
  302. }else{
  303. var checkList = res.data.data;
  304. var content = "";
  305. for(var i=0;i<checkList.length;i++){
  306. var checkItem = checkList[i];
  307. content += (i+1) + "、" + checkItem.msg.replace("不合规","的字词") + "n";
  308. }
  309. uni.showModal({
  310. title: "请删除后重试",
  311. content: content,
  312. showCancel: false
  313. })
  314. console.log(res.data);
  315. }
  316. }
  317. });
  318. }
  319. },
  320. zhuyinDo:function(){
  321. var arr = this.value.split('');
  322. for(var i=0;i<arr.length;i++){
  323. var cur = arr[i];
  324. if(cur=="n" || cur=="↵"){
  325. this.list.push({
  326. value: "enter",
  327. pinyin: "enter"
  328. });
  329. }
  330. if(this.isChinese(cur)){
  331. var pinyin = bopomofo.pinyin(cur);
  332. if(pinyin==cur || pinyin=='null'){
  333. pinyin=" ";
  334. }
  335. var tmp = {
  336. value: cur,
  337. pinyin: pinyin
  338. }
  339. this.list.push(tmp);
  340. }
  341. }
  342. this.status = 1;
  343. this.value = "";
  344. },
  345. reset:function(){
  346. this.value = "";
  347. this.status = 0;
  348. this.list = [];
  349. this.showCanvas = false;
  350. this.down = false;
  351. },
  352. valueChange:function(e){
  353. this.value = e.detail.value;
  354. },
  355. isChinese:function(value){
  356. if (escape(value).indexOf( "%u" )<0) {
  357. return false;
  358. }
  359. return true;
  360. }
  361. }
  362. }
  363. </script>
  364. <style>
  365. @import "../../static/uni.css";
  366. </style>
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/460621
推荐阅读
相关标签
  

闽ICP备14008679号