uniapp使用camera完成指定区域大小扫描拍照功能--自定义拍照区域,相册选择剪裁 打开闪光灯

本文介绍了如何在uniapp项目中利用DCloud插件市场中的图片裁剪插件,展示了如何集成和使用相机功能、裁剪图片以及上传裁剪后的图片进行后续处理的过程。
摘要由CSDN通过智能技术生成

1.代码可以直接用,剪裁功能使用uniapp的插件图片裁剪插件 - DCloud 插件市场

<template>
	<view>
		<camera class="camera-box" style="position: relative;" resolution="high" @initdone="initdone" :flash='flash'
			:style='{width:windowWidth+"px",height:windowHeight+"px"}'>
			<cover-view class='camerabgImage'>
				<cover-view class="active">
					<cover-image class="active-image"
						src="https://oss.nodekoa.com/blog/2020/12/0716073342969601272.png"></cover-image>
 
					<cover-view class="text">将OE码放入框内</cover-view>
 
				</cover-view>
				<cover-view @click="openlamp"
					style="display: flex;flex-direction: column;justify-content: center;align-items: center;color: #fff;margin-top: 130%;">
					<cover-image class="img" src="../../static/off.png" v-if="flash=='off'"></cover-image>
					<cover-image class="img" src="../../static/open.png" v-else></cover-image>
					<!-- <cover-view class="font" style="font-size: 26rpx;margin-top: 20rpx;">打开闪光灯</cover-view> -->
				</cover-view>
				<cover-view
					style="position: absolute;bottom: 0;left: 0;width: 100%;height: 300rpx;display: flex;z-index:999;">
					<cover-view class="icon_flex" @click="takealbum">
						<cover-image class="img" src="../../static/photo.png"></cover-image>
						<cover-view class="font"> 相册 </cover-view>
					</cover-view>
					<cover-view class="icon_flex" @click="takePhoto">
						<cover-view
							style="display: flex;background-color: #fff;align-items: center;justify-content: center;padding: 30rpx;border-radius: 50%;">
							<cover-image class="img" src="../../static/camera.png"></cover-image>
						</cover-view>
						<cover-view class="font">拍照</cover-view>
					</cover-view>
					<cover-view class="icon_flex" @click="manualInput">
						<cover-image class="img" src="../../static/pen.png"></cover-image>
						<cover-view class="font"> 手动输入 </cover-view>
					</cover-view>
				</cover-view>
 
			</cover-view>
		</camera>
		<canvas class="cop" canvas-id="image-canvas"></canvas>
	</view>
</template>
 
<script>
	export default {
		data() {
			return {
				flash: 'off',
				screenWidth: '', //屏幕宽度
				setData: {
					src: ''
				},
				scanShow: true,
				isShowImage: false,
				windowWidth: '',
				windowHeight: '',
				canvas: '',
				img: '',
				maxZoom: null,
				currentZoom: 1,
			}
		},
		onLoad() {
 
			let getWindowInfo = uni.getWindowInfo()
			this.screenWidth = getWindowInfo.screenWidth
			console.log(this.screenWidth, '---------53');
			this.authorize()
			let {
				windowWidth,
				windowHeight
			} = uni.getSystemInfoSync()
			this.windowWidth = windowWidth
			this.windowHeight = windowHeight
 
		},
		onShow() {
			this.currentZoom = 1
		},
		methods: {
			manualInput() {
				uni.navigateTo({
					url: `/pages_my/tally/getOe?false=false`
				})
 
			},
			inputCode(e) {
				console.log(e, '---------90');
			},
			//关闭输入框
			handleCancel() {
				this.showInput = false;
				this.inputVal = ""
			},
			handleConfirm() {
				let _value = this.inputVal.replace(/[, ]/g, '')
				if (_value && _value.length === 17) {
					uni.redirectTo({
						url: `/pages_my/shoplist?vinCode=${_value}`
					});
					this.inputVal = ""
					this.showInput = false
 
				} else {
					uni.showToast({
						title: '请输入正确的17位VIN码!',
						icon: 'none',
						duration: 3000
					});
				}
 
			},
			//开灯
			openlamp() {
				let flag = this.flash
				if (flag == 'off') {
					this.flash = 'on'
				} else {
					this.flash = 'off'
				}
			},
			// 授权
			authorize() {
				uni.getSetting({
					success: (res) => {
						if (!res.authSetting['scope.camera']) {
							uni.authorize({
								scope: 'scope.camera',
								success: () => {
									console.log('授权成功');
								},
								fail: () => {
									uni.showModal({
										title: '提示',
										content: '尚未进行授权,该功能将无法使用',
										success: (res1) => {
											if (res1.confirm) {
												uni.openSetting({
													success: (setting) => {
														// console.log(setting);
														if (setting
															.authSetting[
																'scope.camera'
															]) {
															uni.showToast({
																title: '授权成功!'
															})
														} else {
															uni.showToast({
																title: '授权失败!',
																icon: 'none'
															})
															setTimeout(
																() => {
																	uni.navigateBack()
																}, 1000
															)
														}
													}
												})
											} else {
												uni.navigateBack()
											}
										}
									})
								}
							})
						}
					}
				})
			},
			takePhoto() {
				uni.showLoading({
					title: '上传中...'
				})
				const ctx = wx.createCameraContext()
				ctx.takePhoto({
					quality: 'high',
					success: (res) => {
						this.loadTempImagePath(res.tempImagePath)
					}
				})
			},
			chooseImg() {
				uni.chooseImage({
					count: 1,
					sizeType: ['original', 'compressed'],
					sourceType: ['album'], //这要注意,camera掉拍照,album是打开手机相册
					success: (res) => {
						this.loadTempImagePath(res.tempImagePath)
					}
				})
			},
			takealbum() {
				const that = this
				uni.chooseImage({
					count: 1,
					sizeType: ['original', 'compressed'],
					sourceType: ["album"],
					success: (res) => {
						uni.navigateTo({
							url: "/pages_my/tally/imageCrop?img=" + res.tempFilePaths[0]
						})
						console.log(res.tempFilePaths[0], '-------------175')
					}
				});
			},
			chooseImage(sourceType) {
				const that = this
				uni.chooseImage({
					count: 1,
					sizeType: ['original', 'compressed'],
					sourceType: [sourceType],
					success: (res) => {
						console.log(res, '-------------175');
						if (res.tempFiles[0]['size'] > 20 * 1024 * 1024) {
							uni.showToast({
								title: '图片大小不能超过20M',
								icon: 'none',
								duration: 3000
							});
							return;
						}
						uni.showLoading({
							title: '上传中...'
						})
						if (res.tempFiles[0]['size'] < 5 * 1024 * 1024) {
							that.loadTempImagePath(res.tempFilePaths[0])
						} else {
							uni.compressImage({
								src: res.tempFilePaths[0],
								quality: 80,
								success: res => {
									that.loadTempImagePath(res.tempFilePath, that)
								}
							})
						}
 
					}
				});
			},
			initdone({
				detail: {
					maxZoom
				}
			}) {
				// 最大放大倍速
				this.maxZoom = maxZoom / 2
 
			},
			setZoom(zoom) {
				console.log(this.currentZoom);
				const ctx = uni.createCameraContext()
				if (zoom) {
					// console.log(this.maxZoom);
					if (this.currentZoom >= this.maxZoom) return false
					// console.log(size);
					ctx.setZoom({
						zoom: this.currentZoom += 1
					})
				} else {
					if (this.currentZoom <= 1) return false
					// console.log(size);
					ctx.setZoom({
						zoom: this.currentZoom -= 1
					})
				}
 
			},
			//rpx转px
			rpx2px(rpx) {
				const screenWidth = uni.getSystemInfoSync().screenWidth
				return (screenWidth * Number.parseInt(rpx)) / 750
			},
			loadTempImagePath(url) {
				let {
					windowWidth,
					windowHeight
				} = uni.getSystemInfoSync()
				let x = (windowWidth - this.rpx2px(300)) / 2
				let y = windowHeight * 0.2
				let testc = uni.createCanvasContext('image-canvas');
				testc.drawImage(url, 0, 0, windowWidth, windowHeight)
				testc.draw(false, () => {
					uni.canvasToTempFilePath({
						x: 0,//设置图片x轴起始点
						y: y,//设置图片y轴起始点
						width: this.windowWidth,
						height: this.rpx2px(300),
						canvasId: 'image-canvas',
						fileType: 'jpg',
						quality: 1,
						complete: (res2) => {
							uni.uploadFile({
								url: `${process.uniEnv.baseUrl}/baseVinCode/getVinCodeByImg`,
								filePath: res2.tempFilePath,
								name: 'file',
								formData: {
									file: res2.tempFilePath
								},
								header: {
									'Content-Type': 'multipart/form-data',
								},
								success: response => {
									let res = JSON.parse(response.data.toString("utf8"));
									const {
										data,
										code
									} = res;
									let value = {
										img: res2.tempFilePath,
										font: data
									}
									console.log(res2.tempFilePath,'----------截取后的图片地址');
									if (code == 200) {
										uni.navigateTo({
											url: `/pages_my/tally/getOe?data=${JSON.stringify(value)}`
										})
 
									} else {
										uni.showToast({
											title: res.msg,
											duration: 3000
										});
									}
								},
 
								complete: () => {
									uni.hideLoading()
								}
 
							});
 
						}
					})
				})
			}
		},
 
	}
</script>
 
<style>
	page {
		/* background-color: red; */
		/* background: #fbfbfb; */
		height: auto;
		overflow: hidden;
	}
</style>
<style scoped lang="scss">
	.yulan-box {
		position: relative;
		width: 100%;
		height: 100%;
 
 
	}
 
	.img {
		width: 60rpx;
		height: 60rpx;
	}
 
	.icon_flex {
		flex: 1;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
 
		.font {
			font-size: 26rpx;
			color: #fff;
			margin-top: 30rpx;
		}
	}
 
	.beat {
		width: 33%;
		position: absolute;
		bottom: 0rpx;
		left: 100rpx;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		font-size: 24rpx;
		font-weight: 400;
		color: #ffffff;
 
		.beatImg {
			width: 88rpx;
			height: 88rpx;
			margin-bottom: 30rpx;
		}
	}
 
	.cop {
		width: 100%;
		height: 100vh;
	}
 
	.camera-box {
		position: relative;
		width: 100vw;
		height: 300rpx;
	}
 
	.camera-box .camerabgImage {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0
	}
 
	.camera-box .camerabgImage .active {
		box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.2);
		display: flex;
		flex-direction: column;
		align-items: center;
		position: absolute;
		top: 20%;
		left: 0;
		right: 0;
	}
 
	.camera-box .camerabgImage .active-image {
		box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.2);
		// align-items: center;
		display: block;
		width: 100%;
		height: 300rpx;
	}
 
	.camera-box .camerabgImage .text {
		text-align: center;
		// margin-top: 56rpx;
		// line-height: 100rpx;
 
		font-size: 28rpx;
		font-weight: 400;
		color: #fff;
		line-height: 100rpx
	}
 
	.camera-box .camerabgImage .btn {
		width: 110rpx;
		height: 110rpx;
		border-radius: 50%;
		background: #fff;
		border: 6rpx solid#fff;
 
		position: absolute;
		bottom: 0;
		left: 0;
	}
 
	.camera-box .camerabgImage .btn .button {
		width: 102rpx;
		height: 102rpx;
		border-radius: 50%;
		border: 4rpx solid#000
	}
 
	.camera-box .camerabgImage .btn2 {
		width: 110rpx;
		height: 110rpx;
		border-radius: 50%;
		background: #fff;
		border: 6rpx solid#fff;
 
		position: absolute;
		bottom: 0;
		left: 0;
	}
 
	.camera-box .camerabgImage .btn2 .button2 {
		width: 102rpx;
		height: 102rpx;
		border-radius: 50%;
		border: 4rpx solid#000
	}
 
	.abc {
		position: absolute;
		width: 20rpx;
		height: 20rpx;
		background: #000000;
		left: 117.9px;
		top: 209.6px;
	}
</style>

  • 21
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用camera2扫描二维码并且扫描结束后打开闪光灯的代码: ```java private CameraManager mCameraManager; private String mCameraId; private CameraDevice mCameraDevice; private CameraCaptureSession mCaptureSession; private CaptureRequest.Builder mPreviewRequestBuilder; private TextureView mTextureView; private HandlerThread mBackgroundThread; private Handler mBackgroundHandler; private ImageReader mImageReader; private boolean mFlashSupported; private boolean mFlashState; private final CameraDevice.StateCallback mCameraCallback = new CameraDevice.StateCallback() { @Override public void onOpened(@NonNull CameraDevice cameraDevice) { mCameraDevice = cameraDevice; createCameraPreviewSession(); } @Override public void onDisconnected(@NonNull CameraDevice cameraDevice) { cameraDevice.close(); mCameraDevice = null; } @Override public void onError(@NonNull CameraDevice cameraDevice, int error) { cameraDevice.close(); mCameraDevice = null; } }; private final CameraCaptureSession.StateCallback mSessionCallback = new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) { if (mCameraDevice == null) { return; } mCaptureSession = cameraCaptureSession; try { mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); setAutoFlash(mPreviewRequestBuilder); mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), null, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) { Toast.makeText(getApplicationContext(), "Failed", Toast.LENGTH_SHORT).show(); } }; private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader reader) { mBackgroundHandler.post(new ImageSaver(reader.acquireLatestImage())); } }; private static class ImageSaver implements Runnable { private final Image mImage; ImageSaver(Image image) { mImage = image; } @Override public void run() { // 解析二维码 mImage.close(); } } @Override protected void onResume() { super.onResume(); startBackgroundThread(); if (mTextureView.isAvailable()) { openCamera(mTextureView.getWidth(), mTextureView.getHeight()); } else { mTextureView.setSurfaceTextureListener(mSurfaceTextureListener); } } @Override protected void onPause() { closeCamera(); stopBackgroundThread(); super.onPause(); } private void startBackgroundThread() { mBackgroundThread = new HandlerThread("CameraBackground"); mBackgroundThread.start(); mBackgroundHandler = new Handler(mBackgroundThread.getLooper()); } private void stopBackgroundThread() { mBackgroundThread.quitSafely(); try { mBackgroundThread.join(); mBackgroundThread = null; mBackgroundHandler = null; } catch (InterruptedException e) { e.printStackTrace(); } } private void openCamera(int width, int height) { setUpCameraOutputs(width, height); configureTransform(width, height); mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); try { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { return; } mCameraManager.openCamera(mCameraId, mCameraCallback, null); } catch (CameraAccessException e) { e.printStackTrace(); } } private void closeCamera() { try { mCaptureSession.stopRepeating(); mCaptureSession.abortCaptures(); } catch (CameraAccessException e) { e.printStackTrace(); } mCaptureSession.close(); mCaptureSession = null; mCameraDevice.close(); mCameraDevice = null; mImageReader.close(); mImageReader = null; } private void createCameraPreviewSession() { try { SurfaceTexture texture = mTextureView.getSurfaceTexture(); texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); Surface surface = new Surface(texture); mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); mPreviewRequestBuilder.addTarget(surface); mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.YUV_420_888, 2); mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler); mPreviewRequestBuilder.addTarget(mImageReader.getSurface()); mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()), mSessionCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } private void setUpCameraOutputs(int width, int height) { mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); try { for (String cameraId : mCameraManager.getCameraIdList()) { CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(cameraId); Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING); if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) { StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); if (map == null) { continue; } Size largest = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)), new CompareSizesByArea()); mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), ImageFormat.YUV_420_888, 2); mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), width, height, largest); mCameraId = cameraId; break; } } } catch (CameraAccessException e) { e.printStackTrace(); } } private void configureTransform(int viewWidth, int viewHeight) { if (null == mTextureView || null == mPreviewSize) { return; } int rotation = getWindowManager().getDefaultDisplay().getRotation(); Matrix matrix = new Matrix(); RectF viewRect = new RectF(0, 0, viewWidth, viewHeight); RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth()); float centerX = viewRect.centerX(); float centerY = viewRect.centerY(); if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) { bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY()); matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL); float scale = Math.max((float) viewHeight / mPreviewSize.getHeight(), (float) viewWidth / mPreviewSize.getWidth()); matrix.postScale(scale, scale, centerX, centerY); matrix.postRotate(90 * (rotation - 2), centerX, centerY); } mTextureView.setTransform(matrix); } private static Size chooseOptimalSize(Size[] choices, int width, int height, Size aspectRatio) { List<Size> bigEnough = new ArrayList<>(); for (Size option : choices) { if (option.getHeight() == option.getWidth() * aspectRatio.getHeight() / aspectRatio.getWidth() && option.getWidth() >= width && option.getHeight() >= height) { bigEnough.add(option); } } if (bigEnough.size() > 0) { return Collections.min(bigEnough, new CompareSizesByArea()); } else { return choices[0]; } } private static class CompareSizesByArea implements Comparator<Size> { @Override public int compare(Size lhs, Size rhs) { return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight()); } } private final TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { openCamera(width, height); } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) { configureTransform(width, height); } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { return true; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { } }; private void setAutoFlash(CaptureRequest.Builder requestBuilder) { if (mFlashSupported) { if (mFlashState) { requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); } else { requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); } } } private void setFlashState(boolean state) { mFlashState = state; if (mCaptureSession != null) { try { mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, mFlashState ? CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH : CaptureRequest.CONTROL_AE_MODE_ON); mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), null, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } } ``` 在 `createCameraPreviewSession()` 方法中可以看到,我们添加了一个 `ImageReader` 用于获取相机捕获的数据,我们可以在 `mOnImageAvailableListener` 监听器中对数据进行解析,这里我们可以使用 `Zxing` 库进行解析二维码: ```java private static class ImageSaver implements Runnable { private final Image mImage; ImageSaver(Image image) { mImage = image; } @Override public void run() { ByteBuffer buffer = mImage.getPlanes()[0].getBuffer(); byte[] data = new byte[buffer.remaining()]; buffer.get(data); PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, mImage.getWidth(), mImage.getHeight(), 0, 0, mImage.getWidth(), mImage.getHeight(), false); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); MultiFormatReader reader = new MultiFormatReader(); try { Result result = reader.decode(bitmap); Log.d(TAG, "result: " + result.getText()); } catch (NotFoundException e) { e.printStackTrace(); } finally { mImage.close(); } } } ``` 至于如何打开闪光灯,我们可以在 `setAutoFlash()` 方法中设置 `CaptureRequest.CONTROL_AE_MODE` 参数为 `CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH` 或 `CaptureRequest.CONTROL_AE_MODE_ON` 来控制闪光灯的开关状态。同时,在 `setFlashState()` 方法中可以动态地切换闪光灯状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子伟-H5

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值