uniappで写真の落書きを実現

なぜこの機能を実装するのでしょうか?

uniapp で作成したプロジェクトでは、一部のページに写真を撮る機能があり、カメラを呼び出して写真を撮るだけですが、写真を編集したりマークしたりすることはできません。最適化アイテムではありますが、ある種のアイテムです。

アイデアとロジックを実装する 

美容機能などは一切なく、サインをするようなシンプルな落書きなので、それほど難しいものではありません。アイデアも比較的シンプルです。

1. カメラで撮った写真を受け取る

2. 画像をキャンバスにインポートします

3. キャンバス上のタッチ開始イベントとタッチ移動イベントを監視する

4. キャンバスを画像にエクスポートし、前のページに戻ります。

 参考記事

実装にあたっては他のブロガーさんの記事を参考にさせていただきました。記事へのリンクは以下の通りです。

 https://www.cnblogs.com/buaa17373407hjh/p/12970816.html

 https://www.cnblogs.com/CaraganaMicrophylla/p/16381145.html

実装コード 

 2 つの側面があり、1 つは写真を撮った後、編集ページに直接画像を転送することです。2つ目は、画像プレビューから画像を編集ページに転送する方法です。

カメラロジック

				uni.chooseImage({
					count: 1,
					sourceType: 拍照的话使用['camera'],
					sizeType: ['compressed'],
					success : function(res){
						uni.navigateTo({
							url:照片编辑页面的url,
							events: {
								acceptDataFromOpenedPage: function(data) {
								    console.log(data)
								},
								getEditCompleteImg: function(imgData) {
                                    // 代码处理逻辑,用数组存id和资源
									picturesArray.push({
										id: 自定义值,
										src: imgData中的图片url
									})
								}
							},
							success:function(openRes){
								openRes.eventChannel.emit('acceptDataFromOpenerPage', { data: res.tempFilePaths[0] })
							}
						})
					},
					fail: function(error){
						console.log(error);
					},
					complete: function(res){
						console.log(res);
					}
				})

 chooseImage メソッドと navigateTo メソッドについては、uniapp の公式 Web サイトに具体的なドキュメントがあります。

https://uniapp.dcloud.net.cn/api/media/image.html#chooseimage 

 uni.navigateTo(OBJECT) | uni-app公式サイト

 成功とは、別のページが正常に開かれた後、データがそのページに渡され、画像の URL がコードに渡されたことを意味します。

events は登録されたイベント リスナーであり、データを画像編集ページに再渡すことができます。

フォトロジックを選択

主に uniapp の画像プレビュー機能を呼び出し、長押しによるメニュー項目のポップアップをサポートします。コードは以下のように表示されます

				uni.previewImage({
					urls,    // 图片资源url组成的数组
					current,        // 默认打开的下标
					longPressActions: {
						itemList:['编辑图片'],
						success:function(data){
							console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片')
							// 拿到图片的url     urls[data.index]
							// 关闭图片预览,跳转到图片编辑页面
							plus.nativeUI.closePreviewImage();
							uni.navigateTo({
								url:图片编辑页面的url,
								events: {
									acceptDataFromOpenedPage: function(data) {
									    console.log(data)
									},
									getEditCompleteImg: function(imgData) {
										console.log(imgData)
                                        // 和之前一样的处理逻辑
									}
								},
								success:function(res){
									res.eventChannel.emit('acceptDataFromOpenerPage', { data: urls[data.index] })
								}
							})
						},
						error:function(err){
							console.log(err)
						}
					}
				})

 uni.chooseImage(OBJECT) | uni-app公式サイト

画像編集ロジック 

絵を描くにはキャンバスが必要です。編集保存ボタンとクリアリセットボタン。

保存ボタンのロジックを編集する 

				uni.canvasToTempFilePath({
					canvasId: 'shareCanvas',    // canvas元素的id值
					destHeight: this.initImgHeight,    // initImgHeight是传入图片时获取到的图片高度
					destWidth: this.initImgWidth,        // 传入图片原先的宽度
					success: function (res) {
						// eventChannel.emit('someEvent', {data: 'data from test page for someEvent'});
						vm.eventChannel.emit('getEditCompleteImg', {data: res.tempFilePath});
						// 返回页面
						uni.navigateBack()
					}
				})

 リセットボタンのロジックをクリアする

                // 清除重新绘制
				let vm = this;
				console.log('重新绘制')
				// 重新绘制图片   targetImgUrl为原先图片的url    editWidth是canvas的宽度
				vm.drawContext.drawImage(vm.targetImgUrl,0,0,vm.editWidth,vm.editHeight)
				vm.drawContext.draw()
				// 重新设置颜色    这是封装的一个方法,画笔颜色宽度什么的
				vm.updateDrawContext()

マウントされたキャンバスの幅を取得し、画像の高さと幅の情報を取得してアスペクト比を取得した後、高さを動的に設定します。

			uni.createSelectorQuery().in(this).select(canvas元素设置的类名).boundingClientRect(data => {
				// console.log(JSON.stringify(data))
				// {"id":"","dataset":{},"left":12,"right":308,"top":12,"bottom":315,"width":296,"height":303}
				// this.editHeight = data.height
				
				this.editWidth = data.width
				console.log('读取到的',this.editWidth)
			}).exec()

onLoadで画像のURLを取得し、画像の高さと幅を取得してデータに保存します。

			const ctx = uni.createCanvasContext(canvas元素设置的id值)
			// 设置线条
			this.drawContext = ctx
            let vm = this
            vm.eventChannel.on('acceptDataFromOpenerPage', function(data) {
				console.log(data)
				vm.targetImgUrl = data.data
				// 获取图片的宽高
				uni.getImageInfo({
				    src: data.data,
				    success: function (image) {
						vm.initImgWidth = image.width;
						vm.initImgHeight = image.height;
						console.log('图片高度:',vm.initImgHeight)
						console.log('图片宽度:',vm.initImgWidth)
						console.log('图片纵横比',image.width/image.height)
						// 避免图片拉伸,保持纵横比
						const widthHeight = image.height/image.width
						vm.editHeight = widthHeight*vm.editWidth
						console.log('画布的高度',vm.editHeight)
						console.log('画布的宽度',vm.editWidth)
						vm.drawContext.drawImage(data.data,0,0,vm.editWidth,vm.editHeight)
						vm.drawContext.draw()
						// 设置画笔颜色
						vm.updateDrawContext()
				    },
					error: function (err) {
						console.log(err)
					},
					complete:function(end){
						console.log(end)
					}
				});
			})

ナビゲーション バーの戻りキーと下部の電話の戻りキー

onBackPress に設定

絵の落書き描画ロジック 

getImageInfo では、画像がキャンバスに描画されています。あとはキャンバスの開始タッチイベント、タッチスライドイベント、タッチ終了イベントなどを設定するだけです。

具体的なロジックはこの記事で確認できます。キャンバス署名のロジックも参考記事のリンクにあります。 

ユニアプリでキャンバスを使用する

			touchstart: function (e) {
				// 取出x、y的值
				let {
					x,
					y
				} = e.changedTouches[0]
				// 绘制线条起点
				this.drawContext.beginPath()
				this.drawContext.moveTo(x, y)
				// 起点与移动的连接断开
				this.moveX = ''
				this.moveY = ''
			},
			touchmove: function (e) {
                // 取出x, y的值
                let {
                    x,
                    y
                } = e.changedTouches[0]
                // 防止线条出现断点
                if (this.moveX && this.moveY) {
                    this.drawContext.moveTo(this.moveX, this.moveY)
                    this.drawContext.lineTo(this.moveX, this.moveY)
                }
                this.drawContext.lineTo(x, y)
                this.moveX = x
                this.moveY = y
                this.drawContext.stroke()
                // ture,保留之前的内容
                this.drawContext.draw(true)
			},

 

おすすめ

転載: blog.csdn.net/GhostPaints/article/details/128190868