From 2c80144598552c913d9fecd8a98351dfb6538e21 Mon Sep 17 00:00:00 2001 From: hwf453 Date: Wed, 18 Sep 2024 11:25:31 +0800 Subject: [PATCH] =?UTF-8?q?=E9=AB=98=E9=A3=8E=E9=99=A9=E6=8A=A5=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 3 + .../main/java/com/rehome/zhdcoa/Contans.java | 2 + .../ui/activity/AddDagerEnterApplyActivity.kt | 2 +- .../zhdcoa/ui/activity/LoginActivity.kt | 4 +- .../ui/activity/WorkRiskListActivity.kt | 23 +- .../activity/WorkRiskListHuiBaoActivity.java | 1178 +++++++++++++++++ .../zhdcoa/utils/BitmapCompressUtils.java | 123 ++ .../com/rehome/zhdcoa/utils/BitmapUtil.java | 158 +++ .../com/rehome/zhdcoa/utils/BitmapUtils.java | 117 ++ .../res/layout/activity_work_risk_list.xml | 74 +- .../activity_work_risk_list_hui_bao.xml | 106 ++ 11 files changed, 1748 insertions(+), 42 deletions(-) create mode 100644 app/src/main/java/com/rehome/zhdcoa/ui/activity/WorkRiskListHuiBaoActivity.java create mode 100644 app/src/main/java/com/rehome/zhdcoa/utils/BitmapCompressUtils.java create mode 100644 app/src/main/java/com/rehome/zhdcoa/utils/BitmapUtil.java create mode 100644 app/src/main/java/com/rehome/zhdcoa/utils/BitmapUtils.java create mode 100644 app/src/main/res/layout/activity_work_risk_list_hui_bao.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fd84500..cda078f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -81,6 +81,9 @@ tools:ignore="GoogleAppIndexingWarning" tools:replace="android:allowBackup" tools:targetApi="s"> + ?) { } - }, true, true, "提交数据中...") + }, true, true, "请稍候...") } //修改危化品入厂申请 diff --git a/app/src/main/java/com/rehome/zhdcoa/ui/activity/LoginActivity.kt b/app/src/main/java/com/rehome/zhdcoa/ui/activity/LoginActivity.kt index 2621239..7e021b1 100644 --- a/app/src/main/java/com/rehome/zhdcoa/ui/activity/LoginActivity.kt +++ b/app/src/main/java/com/rehome/zhdcoa/ui/activity/LoginActivity.kt @@ -170,8 +170,8 @@ class LoginActivity : BaseActivityOaToolbarViewBinding() { if (BuildConfig.LOG_ERROR) { // 管理员 -// binding.etUsername.setText("ZHPS_Admin") -// binding.etPassword.setText("Rehome.zhps@996") + binding.etUsername.setText("ZHPS_Admin") + binding.etPassword.setText("Rehome.zhps@996") //马 // binding.etUsername.setText("310482") diff --git a/app/src/main/java/com/rehome/zhdcoa/ui/activity/WorkRiskListActivity.kt b/app/src/main/java/com/rehome/zhdcoa/ui/activity/WorkRiskListActivity.kt index 23d853a..8a2243b 100644 --- a/app/src/main/java/com/rehome/zhdcoa/ui/activity/WorkRiskListActivity.kt +++ b/app/src/main/java/com/rehome/zhdcoa/ui/activity/WorkRiskListActivity.kt @@ -192,35 +192,46 @@ class WorkRiskListActivity : BaseActivityOaToolbarViewBinding videoList = new ArrayList<>(); + + + private GridImageAdapter mAdapter; + private int maxSelectNum = 16; + private List mData = new ArrayList<>(); + + private int language = LanguageConfig.UNKNOWN_LANGUAGE; + private ImageEngine imageEngine; + private VideoPlayerEngine videoPlayerEngine; + private PictureSelectorStyle selectorStyle; + private int chooseModePhoto = SelectMimeType.ofImage(); + private int chooseModeVideo = SelectMimeType.ofVideo(); + private int chooseMode = chooseModePhoto; + private final static String TAG_EXPLAIN_VIEW = "TAG_EXPLAIN_VIEW"; + private final static String TAG = "app"; + private int animationMode = AnimationType.DEFAULT_ANIMATION; + + + private final static int FILE_CHOOSER_RESULT_CODE = 10000; + + private ActivityResultLauncher launcherResult; + + + private ArrayList finalList = new ArrayList<>(); + + + + + private void findView() { + etMs = findViewById(R.id.et_ms); + + recycle = findViewById(R.id.recycle); + cb_crop = findViewById(R.id.cb_crop); + cb_compress = findViewById(R.id.cb_compress); + cb_editor = findViewById(R.id.cb_editor); + + } + + @Override + public int getLayoutId() { + return R.layout.activity_work_risk_list_hui_bao; + } + + @Override + public void initView() { + username = App.getInstance().getUserInfo().getManid(); + findView(); + + + initToolbar("工作情况汇报", "提交", new View.OnClickListener() { + @Override + public void onClick(View v) { + if(TextUtils.isEmpty(etMs.getText().toString().trim())){ + showToast("汇报内容必填"); + }else{ + //提交汇报数据 + mData.clear(); + mData.addAll(mAdapter.getData()); + authenticationLoginAI(); + } + } + }); + + //初始化获取照片和视频 + initTakePhoto(); + } + + @Override + public void initData() { + + Intent intent = getIntent(); + String kksCode = intent.getStringExtra("kks"); + if(!TextUtils.isEmpty(kksCode)){ + //et_kks.setText(kksCode); + } + } + + public void authenticationLoginAI() { + try { + //AI三维登录接口 + String account = Contans.SP.AI_ACCOUNT; + //String strPrivateEncode=RSAAndroid.encryptByPrivateKeyForSpiltStr(Contans.SP.AI_PWD,RSAAndroid.privateRsaKeyLocal); + String strPublicDecode = RSAAndroid.decryptByPublicKeyForSpiltStr(Contans.SP.AI_PWD_ENCODE, RSAAndroid.publicRsaKeyLocal); + showLog("-----------"); + showLog(account); + showLog(strPublicDecode); + + AuthenticationLoginAIUtils.authenticationAILogin(WorkRiskListHuiBaoActivity.this, account, strPublicDecode, new OnAuthenticationLoginListener() { + @Override + public void onAuthenticationSuccess(boolean result, String token) { + if (token != null && token.equals("")) { + showToast("AI三维平台登录失败"); + } else { + uploadDataByNoSave(); + } + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void uploadDataByNoSave() { + finalList.clear(); + for (LocalMedia media : mData) { + if(media.getCompressPath()!=null){ + finalList.add(media.getCompressPath()); + }else{ + if(media.getSandboxPath()!=null){ + finalList.add(media.getSandboxPath()); + } + } + showLog(new Gson().toJson(media)); + } + + showLog(finalList.toString().toLowerCase()); + upLoadQx(); + } + + + + + //上传单条缺陷工单 + private void upLoadQx() { + String url = Contans.BASE_URL_AI_3D_SERVER + Contans.DAYLY_RISK_LIST_HUIBAO; + showLog(url); + Request request = NoHttp.createStringRequest(url, RequestMethod.POST); + + + +// request.add("kks", qxItemUpload.getKks()); +// request.add("jz", qxItemUpload.getJz()); +// request.add("zy", qxItemUpload.getZy()); +// request.add("xydj", qxItemUpload.getXydj()); +// request.add("gzlx", qxItemUpload.getGzlx()); +// request.add("bgr", username); +// request.add("gzqx", qxItemUpload.getGzqx()); +// request.add("date", qxItemUpload.getDate()); + + + + + if (mData!=null&&mData.size()>0) { + + for (LocalMedia localMedia : mData) { + showLog(new Gson().toJson(localMedia)); + if(localMedia.getCompressPath()!=null){ + request.add("file", new File(localMedia.getCompressPath())); + }else{ + if(localMedia.getSandboxPath()!=null){ + request.add("file", new File(localMedia.getSandboxPath())); + } + } + } + } + + + if(Contans.BASE_URL_AI_3D_SERVER.equals(Contans.BASE_URL_AI_3D_SERVER_EXTRANET)){ + SSLSocketFactory socketFactory = NohttpUtils.getSSLSocketFactory(context); + if (socketFactory != null) { + request.setSSLSocketFactory(socketFactory); + request.setHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }); + } + } + + NohttpUtils.getInstance().add(this,0, request, new HttpListener() { + + @Override + public void onSucceed(int what, Response response) { + + showLog("----------------"); + String result = response.get(); + showLog(result); + + MemberInfoStatisticsV1Bean bean = GsonToBean(result, MemberInfoStatisticsV1Bean.class); + if (bean != null && bean.getData() != null) { + MemberInfoStatisticsV1Bean.Data item = bean.getData(); + //Log.i("app","--->"); + //Log.i("app",new Gson().toJson(item)); + + } + } + + @Override + public void onFailed(int what, Response response) { + + } + },true,true,"请稍候..."); + } + + private void clearView() { + etMs.setText(""); + mAdapter.getData().clear(); + mAdapter.notifyDataSetChanged(); + } + + + private void initTakePhoto() { + launcherResult = createActivityResultLauncher(); + + //android 10 以上 + if (getExternalFilesDir(null) != null) { + path = Objects.requireNonNull(getExternalFilesDir(null)).getPath() + "/images"; + } else { + path = getFilesDir().getPath() + "/images"; + } + + clearImageDiskCache(WorkRiskListHuiBaoActivity.this); + + FullyGridLayoutManager manager = new FullyGridLayoutManager(this, + 4, GridLayoutManager.VERTICAL, false); + recycle.setLayoutManager(manager); + RecyclerView.ItemAnimator itemAnimator = recycle.getItemAnimator(); + if (itemAnimator != null) { + ((SimpleItemAnimator) itemAnimator).setSupportsChangeAnimations(false); + } + recycle.addItemDecoration(new GridSpacingItemDecoration(4, + DensityUtil.dip2px(this, 8), false)); + mAdapter = new GridImageAdapter(this, mData); + mAdapter.setSelectMax(maxSelectNum); + recycle.setAdapter(mAdapter); + + + imageEngine = GlideEngine.createGlideEngine(); + selectorStyle = new PictureSelectorStyle(); + mAdapter.setOnItemClickListener(new GridImageAdapter.OnItemClickListener() { + @Override + public void onItemClick(View v, int position) { + showLog("onItemClick"); + // 预览图片、视频、音频 + PictureSelector.create(WorkRiskListHuiBaoActivity.this) + .openPreview() + .setImageEngine(imageEngine) + .setVideoPlayerEngine(videoPlayerEngine) + .setSelectorUIStyle(selectorStyle) + .setLanguage(language) + .isAutoVideoPlay(false) + .isLoopAutoVideoPlay(false) + .isPreviewFullScreenMode(true) + .isVideoPauseResumePlay(false) + .setCustomLoadingListener(getCustomLoadingListener()) + .isPreviewZoomEffect(chooseMode != SelectMimeType.ofAudio(), recycle) + .setAttachViewLifecycle(new IBridgeViewLifecycle() { + @Override + public void onViewCreated(Fragment fragment, View view, Bundle savedInstanceState) { +// PictureSelectorPreviewFragment previewFragment = (PictureSelectorPreviewFragment) fragment; +// MediumBoldTextView tvShare = view.findViewById(R.id.tv_share); +// tvShare.setVisibility(View.VISIBLE) +// previewFragment.addAminViews(tvShare); +// ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) tvShare.getLayoutParams(); +// layoutParams.topMargin = cb_preview_full.isChecked() ? DensityUtil.getStatusBarHeight(getContext()) : 0; +// tvShare.setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View v) { +// PicturePreviewAdapter previewAdapter = previewFragment.getAdapter(); +// ViewPager2 viewPager2 = previewFragment.getViewPager2(); +// LocalMedia media = previewAdapter.getItem(viewPager2.getCurrentItem()); +// ToastUtils.showToast(fragment.getContext(), "自定义分享事件:" + viewPager2.getCurrentItem()); +// } +// }); + } + + @Override + public void onDestroy(Fragment fragment) { + //取消注册广播,防止内存泄漏 + //localBroadcastManager.unregisterReceiver( myReceiver ); +// if (cb_preview_full.isChecked()) { +// // 如果是全屏预览模式且是startFragmentPreview预览,回到自己的界面时需要恢复一下自己的沉浸式状态 +// // 以下提供2种解决方案: +// // 1.通过ImmersiveManager.immersiveAboveAPI23重新设置一下沉浸式 +// int statusBarColor = ContextCompat.getColor(getContext(), R.color.ps_color_grey); +// int navigationBarColor = ContextCompat.getColor(getContext(), R.color.ps_color_grey); +// ImmersiveManager.immersiveAboveAPI23(MainActivityJava.this, +// true, true, +// statusBarColor, navigationBarColor, false); +// // 2.让自己的titleBar的高度加上一个状态栏高度且内容PaddingTop下沉一个状态栏的高度 +// } + } + }) + .setInjectLayoutResourceListener(new OnInjectLayoutResourceListener() { + @Override + public int getLayoutResourceId(Context context, int resourceSource) { + return resourceSource == InjectResourceSource.PREVIEW_LAYOUT_RESOURCE + ? R.layout.ps_custom_fragment_preview + : InjectResourceSource.DEFAULT_LAYOUT_RESOURCE; + } + }) + .setExternalPreviewEventListener(new MyExternalPreviewEventListener()) + .setInjectActivityPreviewFragment(new OnInjectActivityPreviewListener() { + @Override + public PictureSelectorPreviewFragment onInjectPreviewFragment() { + return null; + } + }) + .startActivityPreview(position, true, mAdapter.getData()); + } + + @Override + public void openPicture() { + showLog("openPicture"); + // 进入相册 + PictureSelectionModel selectionModel = PictureSelector.create(WorkRiskListHuiBaoActivity.this) + .openGallery(chooseMode) + .setSelectorUIStyle(selectorStyle) + .setImageEngine(imageEngine) + .setVideoPlayerEngine(videoPlayerEngine) + .setCropEngine(getCropFileEngine()) + .setCompressEngine(getCompressFileEngine()) + .setSandboxFileEngine(new MeSandboxFileEngine()) + .setCameraInterceptListener(getCustomCameraEvent()) + .setRecordAudioInterceptListener(new MeOnRecordAudioInterceptListener()) + .setSelectLimitTipsListener(new MeOnSelectLimitTipsListener()) + .setEditMediaInterceptListener(getCustomEditMediaEvent()) + .setPermissionDescriptionListener(getPermissionDescriptionListener()) + .setPreviewInterceptListener(getPreviewInterceptListener()) + .setPermissionDeniedListener(getPermissionDeniedListener()) + .setAddBitmapWatermarkListener(getAddBitmapWatermarkListener()) + .setVideoThumbnailListener(getVideoThumbnailEventListener()) + .isAutoVideoPlay(false) + .isLoopAutoVideoPlay(false) + .isPageSyncAlbumCount(true) + .setRecordVideoMaxSecond(10) + .setCustomLoadingListener(getCustomLoadingListener()) + .setQueryFilterListener(new OnQueryFilterListener() { + @Override + public boolean onFilter(LocalMedia media) { + return false; + } + }) + .setSelectionMode(SelectModeConfig.MULTIPLE) + .setLanguage(language) + .setOutputCameraDir(getSandboxCameraOutputPath()) + .setQuerySandboxDir(getSandboxCameraOutputPath()) + .isDisplayTimeAxis(true) + .isOnlyObtainSandboxDir(false) + .isPageStrategy(true) + .isOriginalControl(false) + .isDisplayCamera(true) + .isOpenClickSound(false) + .setSkipCropMimeType(getNotSupportCrop()) + .isFastSlidingSelect(true) + //.setOutputCameraImageFileName("luck.jpeg") + //.setOutputCameraVideoFileName("luck.mp4") + .isWithSelectVideoImage(true) + .isPreviewFullScreenMode(true) + .isVideoPauseResumePlay(false) + .isPreviewZoomEffect(true) + .isPreviewImage(true) + .isPreviewVideo(true) + .isPreviewAudio(true) + .setGridItemSelectAnimListener(null) + //.setQueryOnlyMimeType(PictureMimeType.ofGIF()) + .isMaxSelectEnabledMask(true) + .setMaxSelectNum(maxSelectNum) + .setMaxVideoSelectNum(maxSelectNum) + .setRecyclerAnimationMode(animationMode) + .isGif(false) + .setSelectedData(mAdapter.getData()); + forSelectResult(selectionModel); + } + }); + + } + + + + /** + * 清除图片磁盘缓存 + */ + public void clearImageDiskCache(Context context) { + try { + if (Looper.myLooper() == Looper.getMainLooper()) { + new Thread(new Runnable() { + @Override + public void run() { + Glide.get(context).clearDiskCache(); + } + }).start(); + } else { + Glide.get(context).clearDiskCache(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void forSelectResult(PictureSelectionModel model) { + model.forResult(launcherResult); + } + + + /** + * 处理选择结果 + * + * @param result + */ + private void analyticalSelectResults(ArrayList result) { + showLog("result"); + showLog(String.valueOf(result.size())); + mData = result; + for (LocalMedia media : result) { + if (media.getWidth() == 0 || media.getHeight() == 0) { + if (PictureMimeType.isHasImage(media.getMimeType())) { + MediaExtraInfo imageExtraInfo = MediaUtils.getImageSize(context, media.getPath()); + media.setWidth(imageExtraInfo.getWidth()); + media.setHeight(imageExtraInfo.getHeight()); + } + } + + Log.i(TAG, "文件名: " + media.getFileName()); + Log.i(TAG, "是否压缩:" + media.isCompressed()); + Log.i(TAG, "压缩:" + media.getCompressPath()); + Log.i(TAG, "初始路径:" + media.getPath()); + Log.i(TAG, "绝对路径:" + media.getRealPath()); + Log.i(TAG, "是否裁剪:" + media.isCut()); + Log.i(TAG, "裁剪路径:" + media.getCutPath()); + Log.i(TAG, "是否开启原图:" + media.isOriginal()); + Log.i(TAG, "原图路径:" + media.getOriginalPath()); + Log.i(TAG, "沙盒路径:" + media.getSandboxPath()); + Log.i(TAG, "水印路径:" + media.getWatermarkPath()); + Log.i(TAG, "视频缩略图:" + media.getVideoThumbnailPath()); + Log.i(TAG, "原始宽高: " + media.getWidth() + "x" + media.getHeight()); + Log.i(TAG, "裁剪宽高: " + media.getCropImageWidth() + "x" + media.getCropImageHeight()); + Log.i(TAG, "文件大小: " + PictureFileUtils.formatAccurateUnitFileSize(media.getSize())); + Log.i(TAG, "文件时长: " + media.getDuration()); + + if(media.getCompressPath()!=null){ + + ///storage/emulated/0/Android/data/com.rehome.dywoa/cache/luban_disk_cache/CMP_20240627183056629.jpg + ///storage/emulated/0/Android/data/com.rehome.dywoa/files/Pictures/IMG_20240628100106501.jpeg + Bitmap bitmap =BitmapFactory.decodeFile(media.getSandboxPath()); + Bitmap bitmap1 =BitmapFactory.decodeFile(media.getCompressPath()); + showLog("沙盒宽高---------------"); + showLog("w:"+String.valueOf(bitmap.getWidth()) + " h:" + bitmap.getHeight()); + showLog("压缩宽高---------------"); + showLog("w:"+String.valueOf(bitmap1.getWidth()) + " h:" + bitmap1.getHeight()); + showLog("压缩文件大小---------------"); + File fileCompressPath=new File(media.getCompressPath()); + showLog("压缩文件大小: " + String.valueOf(fileCompressPath.length())); + } +// if(media.getCompressPath()==null&&media.getSandboxPath()!=null){ +// int indexOf = media.getSandboxPath().lastIndexOf("."); +// String postfix = indexOf != -1 ? media.getSandboxPath().substring(indexOf) : ".jpg"; +// String fileName = DateUtils.getCreateFileName("CMP_") + postfix; +// +// String dirPic = media.getSandboxPath().substring(0,media.getSandboxPath().lastIndexOf("/")); +// String outputPath = dirPic + File.separator+fileName; +// showLog(dirPic); +// showLog(outputPath); +// //167903 读取图片路径按比例大小压缩方法 w:614 h:819 +// Bitmap bitmap = BitmapCompressUtils.getimage(media.getSandboxPath()); +// //66759 图片用BITMAP按比例压缩 w:384 h:512 +// //Bitmap bitmap = BitmapCompressUtils.compressScale(BitmapFactory.decodeFile(media.getSandboxPath())); +// BitmapUtil.saveBitmap(outputPath,bitmap); +// File fileCompressPath=new File(outputPath); +// Log.i(TAG, "压缩文件大小: " + String.valueOf(fileCompressPath.length())); +// } + + + + //BitmapCompressUtils + +// String extensionName = FileUtils.getFileType(videoFileName); +// videoCompressFilePath = context.getExternalFilesDir(null).getPath() + "/Movies/" + UUID.randomUUID() + "_compress_video." + extensionName; +// showLog(videoCompressFilePath); +// if(chooseMode==chooseModeVideo){ +// VideoCompress.compressVideoLow(videoFilePath, videoCompressFilePath, new VideoCompress.CompressListener() { +// @Override +// public void onStart() { +// progressDialog.show(); +// } +// +// @Override +// public void onSuccess() { +// progressDialog.dismiss(); +// showLog(videoCompressFilePath); +// File file = new File(videoCompressFilePath); +// showLog("压缩后文件大小:"+String.valueOf(file.length())); +// +// } +// +// @Override +// public void onFail() { +// progressDialog.dismiss(); +// } +// +// @Override +// public void onProgress(float percent) { +// progressDialog.setProgress((int) percent); +// } +// }); +// } + + + } + + runOnUiThread(new Runnable() { + @Override + public void run() { + boolean isMaxSize = result.size() == mAdapter.getSelectMax(); + int oldSize = mAdapter.getData().size(); + mAdapter.notifyItemRangeRemoved(0, isMaxSize ? oldSize + 1 : oldSize); + mAdapter.getData().clear(); + mAdapter.getData().addAll(result); + mAdapter.notifyItemRangeInserted(0, result.size()); + } + }); + } + + /** + * 自定义loading + * + * @return + */ + private OnCustomLoadingListener getCustomLoadingListener() { + return null; + } + + /** + * 外部预览监听事件 + */ + private class MyExternalPreviewEventListener implements OnExternalPreviewEventListener { + + @Override + public void onPreviewDelete(int position) { + mAdapter.remove(position); + mAdapter.notifyItemRemoved(position); + } + + @Override + public boolean onLongPressDownload(LocalMedia media) { + return false; + } + } + + /** + * 裁剪引擎 + * + * @return + */ + private ImageFileCropEngine getCropFileEngine() { + return cb_crop.isChecked() ? new ImageFileCropEngine() : null; + } + + /** + * 自定义裁剪 + */ + private class ImageFileCropEngine implements CropFileEngine { + + @Override + public void onStartCrop(Fragment fragment, Uri srcUri, Uri destinationUri, ArrayList dataSource, int requestCode) { + UCrop.Options options = buildOptions(); + UCrop uCrop = UCrop.of(srcUri, destinationUri, dataSource); + uCrop.withOptions(options); + uCrop.setImageEngine(new UCropImageEngine() { + @Override + public void loadImage(Context context, String url, ImageView imageView) { + if (!ImageLoaderUtils.assertValidRequest(context)) { + return; + } + Glide.with(context).load(url).override(180, 180).into(imageView); + } + + @Override + public void loadImage(Context context, Uri url, int maxWidth, int maxHeight, OnCallbackListener call) { + Glide.with(context).asBitmap().load(url).override(maxWidth, maxHeight).into(new CustomTarget() { + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + if (call != null) { + call.onCall(resource); + } + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + if (call != null) { + call.onCall(null); + } + } + }); + } + }); + uCrop.start(fragment.requireActivity(), fragment, requestCode); + } + } + + /** + * 配制UCrop,可根据需求自我扩展 + * + * @return + */ + private UCrop.Options buildOptions() { + UCrop.Options options = new UCrop.Options(); + options.setHideBottomControls(false); + options.setFreeStyleCropEnabled(false); + options.setShowCropFrame(true); + options.setShowCropGrid(true); + options.setCircleDimmedLayer(false); + options.withAspectRatio(0, 0); + options.setCropOutputPathDir(getSandboxPath()); + options.isCropDragSmoothToCenter(false); + options.setSkipCropMimeType(getNotSupportCrop()); + options.isForbidCropGifWebp(false); + options.isForbidSkipMultipleCrop(true); + options.setMaxScaleMultiplier(100); + if (selectorStyle != null && selectorStyle.getSelectMainStyle().getStatusBarColor() != 0) { + SelectMainStyle mainStyle = selectorStyle.getSelectMainStyle(); + boolean isDarkStatusBarBlack = mainStyle.isDarkStatusBarBlack(); + int statusBarColor = mainStyle.getStatusBarColor(); + options.isDarkStatusBarBlack(isDarkStatusBarBlack); + if (StyleUtils.checkStyleValidity(statusBarColor)) { + options.setStatusBarColor(statusBarColor); + options.setToolbarColor(statusBarColor); + } else { + options.setStatusBarColor(ContextCompat.getColor(context, com.luck.picture.lib.R.color.ps_color_grey)); + options.setToolbarColor(ContextCompat.getColor(context, com.luck.picture.lib.R.color.ps_color_grey)); + } + TitleBarStyle titleBarStyle = selectorStyle.getTitleBarStyle(); + if (StyleUtils.checkStyleValidity(titleBarStyle.getTitleTextColor())) { + options.setToolbarWidgetColor(titleBarStyle.getTitleTextColor()); + } else { + options.setToolbarWidgetColor(ContextCompat.getColor(context, com.luck.picture.lib.R.color.ps_color_white)); + } + } else { + options.setStatusBarColor(ContextCompat.getColor(context, com.luck.picture.lib.R.color.ps_color_grey)); + options.setToolbarColor(ContextCompat.getColor(context, com.luck.picture.lib.R.color.ps_color_grey)); + options.setToolbarWidgetColor(ContextCompat.getColor(context, com.luck.picture.lib.R.color.ps_color_white)); + } + return options; + } + + /** + * 创建自定义输出目录 + * + * @return + */ + private String getSandboxPath() { + File externalFilesDir = context.getExternalFilesDir(""); + File customFile = new File(externalFilesDir.getAbsolutePath(), "Sandbox"); + if (!customFile.exists()) { + customFile.mkdirs(); + } + return customFile.getAbsolutePath() + File.separator; + } + + private String[] getNotSupportCrop() { + //跳过裁剪GIF +// if (true) { +// return new String[]{PictureMimeType.ofGIF(), PictureMimeType.ofWEBP()}; +// } + return null; + } + + /** + * 压缩引擎 + * + * @return + */ + private ImageFileCompressEngine getCompressFileEngine() { + return cb_compress.isChecked() ? new ImageFileCompressEngine() : null; + } + + /** + * 自定义压缩 + */ + private static class ImageFileCompressEngine implements CompressFileEngine { + + @Override + public void onStartCompress(Context context, ArrayList source, OnKeyValueResultCallbackListener call) { + Luban.with(context).load(source).ignoreBy(100).setRenameListener(new OnRenameListener() { + @Override + public String rename(String filePath) { + int indexOf = filePath.lastIndexOf("."); + String postfix = indexOf != -1 ? filePath.substring(indexOf) : ".jpg"; + return DateUtils.getCreateFileName("CMP_") + postfix; + } + }).filter(new CompressionPredicate() { + @Override + public boolean apply(String path) { + if (PictureMimeType.isUrlHasImage(path) && !PictureMimeType.isHasHttp(path)) { + return true; + } + return !PictureMimeType.isUrlHasGif(path); + } + }).setCompressListener(new OnNewCompressListener() { + @Override + public void onStart() { + + } + + @Override + public void onSuccess(String source, File compressFile) { + if (call != null) { + call.onCallback(source, compressFile.getAbsolutePath()); + } + } + + @Override + public void onError(String source, Throwable e) { + if (call != null) { + call.onCallback(source, null); + } + } + }).launch(); + } + } + + /** + * 自定义沙盒文件处理 + */ + private static class MeSandboxFileEngine implements UriToFileTransformEngine { + + @Override + public void onUriToFileAsyncTransform(Context context, String srcPath, String mineType, OnKeyValueResultCallbackListener call) { + if (call != null) { + call.onCallback(srcPath, SandboxTransformUtils.copyPathToSandbox(context, srcPath, mineType)); + } + } + } + + /** + * 自定义相机事件 + * + * @return + */ + private OnCameraInterceptListener getCustomCameraEvent() { + return null; + } + + /** + * 录音回调事件 + */ + private static class MeOnRecordAudioInterceptListener implements OnRecordAudioInterceptListener { + + @Override + public void onRecordAudio(Fragment fragment, int requestCode) { + String[] recordAudio = {android.Manifest.permission.RECORD_AUDIO}; + if (PermissionChecker.isCheckSelfPermission(fragment.getContext(), recordAudio)) { + startRecordSoundAction(fragment, requestCode); + } else { + addPermissionDescription(false, (ViewGroup) fragment.requireView(), recordAudio); + PermissionChecker.getInstance().requestPermissions(fragment, + new String[]{android.Manifest.permission.RECORD_AUDIO}, new PermissionResultCallback() { + @Override + public void onGranted() { + removePermissionDescription((ViewGroup) fragment.requireView()); + startRecordSoundAction(fragment, requestCode); + } + + @Override + public void onDenied() { + removePermissionDescription((ViewGroup) fragment.requireView()); + } + }); + } + } + } + + /** + * 启动录音意图 + * + * @param fragment + * @param requestCode + */ + private static void startRecordSoundAction(Fragment fragment, int requestCode) { + Intent recordAudioIntent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); + if (recordAudioIntent.resolveActivity(fragment.requireActivity().getPackageManager()) != null) { + fragment.startActivityForResult(recordAudioIntent, requestCode); + } else { + ToastUtils.showToast(fragment.getContext(), "The system is missing a recording component"); + } + } + + /** + * 添加权限说明 + * + * @param viewGroup + * @param permissionArray + */ + private static void addPermissionDescription(boolean isHasSimpleXCamera, ViewGroup viewGroup, String[] permissionArray) { + int dp10 = DensityUtil.dip2px(viewGroup.getContext(), 10); + int dp15 = DensityUtil.dip2px(viewGroup.getContext(), 15); + MediumBoldTextView view = new MediumBoldTextView(viewGroup.getContext()); + view.setTag(TAG_EXPLAIN_VIEW); + view.setTextSize(14); + view.setTextColor(Color.parseColor("#333333")); + view.setPadding(dp10, dp15, dp10, dp15); + + String title; + String explain; + + if (TextUtils.equals(permissionArray[0], PermissionConfig.CAMERA[0])) { + title = "相机权限使用说明"; + explain = "相机权限使用说明\n用户app用于拍照/录视频"; + } else if (TextUtils.equals(permissionArray[0], Manifest.permission.RECORD_AUDIO)) { + if (isHasSimpleXCamera) { + title = "麦克风权限使用说明"; + explain = "麦克风权限使用说明\n用户app用于录视频时采集声音"; + } else { + title = "录音权限使用说明"; + explain = "录音权限使用说明\n用户app用于采集声音"; + } + } else { + title = "存储权限使用说明"; + explain = "存储权限使用说明\n用户app写入/下载/保存/读取/修改/删除图片、视频、文件等信息"; + } + int startIndex = 0; + int endOf = startIndex + title.length(); + SpannableStringBuilder builder = new SpannableStringBuilder(explain); + builder.setSpan(new AbsoluteSizeSpan(DensityUtil.dip2px(viewGroup.getContext(), 16)), startIndex, endOf, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + builder.setSpan(new ForegroundColorSpan(0xFF333333), startIndex, endOf, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + view.setText(builder); + view.setBackground(ContextCompat.getDrawable(viewGroup.getContext(), R.drawable.ps_demo_permission_desc_bg)); + + if (isHasSimpleXCamera) { + RelativeLayout.LayoutParams layoutParams = + new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT); + layoutParams.topMargin = DensityUtil.getStatusBarHeight(viewGroup.getContext()); + layoutParams.leftMargin = dp10; + layoutParams.rightMargin = dp10; + viewGroup.addView(view, layoutParams); + } else { + ConstraintLayout.LayoutParams layoutParams = + new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, ConstraintLayout.LayoutParams.WRAP_CONTENT); + layoutParams.topToBottom = R.id.title_bar; + layoutParams.leftToLeft = ConstraintSet.PARENT_ID; + layoutParams.leftMargin = dp10; + layoutParams.rightMargin = dp10; + viewGroup.addView(view, layoutParams); + } + } + + /** + * 移除权限说明 + * + * @param viewGroup + */ + private static void removePermissionDescription(ViewGroup viewGroup) { + View tagExplainView = viewGroup.findViewWithTag(TAG_EXPLAIN_VIEW); + viewGroup.removeView(tagExplainView); + } + + /** + * 拦截自定义提示 + */ + private static class MeOnSelectLimitTipsListener implements OnSelectLimitTipsListener { + + @Override + public boolean onSelectLimitTips(Context context, @Nullable LocalMedia media, PictureSelectionConfig config, int limitType) { + if (limitType == SelectLimitType.SELECT_MIN_SELECT_LIMIT) { + ToastUtils.showToast(context, "图片最少不能低于" + config.minSelectNum + "张"); + return true; + } else if (limitType == SelectLimitType.SELECT_MIN_VIDEO_SELECT_LIMIT) { + ToastUtils.showToast(context, "视频最少不能低于" + config.minVideoSelectNum + "个"); + return true; + } else if (limitType == SelectLimitType.SELECT_MIN_AUDIO_SELECT_LIMIT) { + ToastUtils.showToast(context, "音频最少不能低于" + config.minAudioSelectNum + "个"); + return true; + } + return false; + } + } + + /** + * 自定义编辑事件 + * + * @return + */ + private OnMediaEditInterceptListener getCustomEditMediaEvent() { + return cb_editor.isChecked() ? new MeOnMediaEditInterceptListener(getSandboxPath(), buildOptions()) : null; + } + + + /** + * 自定义编辑 + */ + private static class MeOnMediaEditInterceptListener implements OnMediaEditInterceptListener { + private final String outputCropPath; + private final UCrop.Options options; + + public MeOnMediaEditInterceptListener(String outputCropPath, UCrop.Options options) { + this.outputCropPath = outputCropPath; + this.options = options; + } + + @Override + public void onStartMediaEdit(Fragment fragment, LocalMedia currentLocalMedia, int requestCode) { + String currentEditPath = currentLocalMedia.getAvailablePath(); + Uri inputUri = PictureMimeType.isContent(currentEditPath) + ? Uri.parse(currentEditPath) : Uri.fromFile(new File(currentEditPath)); + Uri destinationUri = Uri.fromFile( + new File(outputCropPath, DateUtils.getCreateFileName("CROP_") + ".jpeg")); + UCrop uCrop = UCrop.of(inputUri, destinationUri); + options.setHideBottomControls(false); + uCrop.withOptions(options); + uCrop.setImageEngine(new UCropImageEngine() { + @Override + public void loadImage(Context context, String url, ImageView imageView) { + if (!ImageLoaderUtils.assertValidRequest(context)) { + return; + } + Glide.with(context).load(url).override(180, 180).into(imageView); + } + + @Override + public void loadImage(Context context, Uri url, int maxWidth, int maxHeight, OnCallbackListener call) { + Glide.with(context).asBitmap().load(url).override(maxWidth, maxHeight).into(new CustomTarget() { + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + if (call != null) { + call.onCall(resource); + } + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + if (call != null) { + call.onCall(null); + } + } + }); + } + }); + uCrop.startEdit(fragment.requireActivity(), fragment, requestCode); + } + } + + /** + * 权限说明 + * + * @return + */ + private OnPermissionDescriptionListener getPermissionDescriptionListener() { + return null; + } + + /** + * 自定义预览 + * + * @return + */ + private OnPreviewInterceptListener getPreviewInterceptListener() { + return null; + } + + /** + * 权限拒绝后回调 + * + * @return + */ + private OnPermissionDeniedListener getPermissionDeniedListener() { + return null; + } + + /** + * 给图片添加水印 + */ + private OnBitmapWatermarkEventListener getAddBitmapWatermarkListener() { + return null; + } + + /** + * 处理视频缩略图 + */ + private OnVideoThumbnailEventListener getVideoThumbnailEventListener() { + return null; + } + + /** + * 创建相机自定义输出目录 + * + * @return + */ + private String getSandboxCameraOutputPath() { + return ""; + } + + /** + * 创建一个ActivityResultLauncher + * + * @return + */ + private ActivityResultLauncher createActivityResultLauncher() { + return registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), + new ActivityResultCallback() { + @Override + public void onActivityResult(ActivityResult result) { + int resultCode = result.getResultCode(); + if (resultCode == RESULT_OK) { + ArrayList selectList = PictureSelector.obtainSelectorList(result.getData()); + analyticalSelectResults(selectList); + } + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/rehome/zhdcoa/utils/BitmapCompressUtils.java b/app/src/main/java/com/rehome/zhdcoa/utils/BitmapCompressUtils.java new file mode 100644 index 0000000..0377416 --- /dev/null +++ b/app/src/main/java/com/rehome/zhdcoa/utils/BitmapCompressUtils.java @@ -0,0 +1,123 @@ +package com.rehome.zhdcoa.utils; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.text.TextUtils; +import android.util.Log; + +import com.rehome.zhdcoa.BuildConfig; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +public class BitmapCompressUtils { + + /** + * 质量压缩方法 + * @param image + * @return + */ + public static Bitmap compressImage(Bitmap image) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 + int options = 90; + while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩 + baos.reset(); // 重置baos即清空baos + image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中 + options -= 10;// 每次都减少10 + } + ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中 + Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片 + return bitmap; + } + + /** + * 图片按比例大小压缩方法 + * @param srcPath (根据路径获取图片并压缩) + * @return + */ + public static Bitmap getimage(String srcPath) { + BitmapFactory.Options newOpts = new BitmapFactory.Options(); + // 开始读入图片,此时把options.inJustDecodeBounds 设回true了 + newOpts.inJustDecodeBounds = true; + Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空 + newOpts.inJustDecodeBounds = false; + int w = newOpts.outWidth; + int h = newOpts.outHeight; + // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 + float hh = 800f;// 这里设置高度为800f + float ww = 480f;// 这里设置宽度为480f + // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 + int be = 1;// be=1表示不缩放 + if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放 + be = (int) (newOpts.outWidth / ww); + } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放 + be = (int) (newOpts.outHeight / hh); + } + if (be <= 0) + be = 1; + newOpts.inSampleSize = be;// 设置缩放比例 + // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了 + bitmap = BitmapFactory.decodeFile(srcPath, newOpts); + showLog("---------------"); + showLog("w:"+String.valueOf(bitmap.getWidth()) + " h:" + bitmap.getHeight()); + return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩 + } + /** + * 图片按比例大小压缩方法 + * @param image (根据Bitmap图片压缩) + * @return + */ + public static Bitmap compressScale(Bitmap image) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + image.compress(Bitmap.CompressFormat.JPEG, 100, baos); + // 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出 + if (baos.toByteArray().length / 1024 > 1024) { + baos.reset();// 重置baos即清空baos + image.compress(Bitmap.CompressFormat.JPEG, 80, baos);// 这里压缩50%,把压缩后的数据存放到baos中 + } + ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray()); + BitmapFactory.Options newOpts = new BitmapFactory.Options(); + // 开始读入图片,此时把options.inJustDecodeBounds 设回true了 + newOpts.inJustDecodeBounds = true; + Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); + newOpts.inJustDecodeBounds = false; + int w = newOpts.outWidth; + int h = newOpts.outHeight; + showLog("---------------"); + showLog("w:"+String.valueOf(w) + " h:" + h); + // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 + // float hh = 800f;// 这里设置高度为800f + // float ww = 480f;// 这里设置宽度为480f + float hh = 512f; + float ww = 512f; + // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 + int be = 1;// be=1表示不缩放 + if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放 + be = (int) (newOpts.outWidth / ww); + } else if (w < h && h > hh) { // 如果高度高的话根据高度固定大小缩放 + be = (int) (newOpts.outHeight / hh); + } + if (be <= 0) + be = 1; + newOpts.inSampleSize = be; // 设置缩放比例 + // newOpts.inPreferredConfig = Config.RGB_565;//降低图片从ARGB888到RGB565 + // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了 + isBm = new ByteArrayInputStream(baos.toByteArray()); + bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); + showLog("---------------"); + showLog("w:"+String.valueOf(bitmap.getWidth()) + " h:" + bitmap.getHeight()); + return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩 + //return bitmap; + } + + public static void showLog(String logText) { + if (BuildConfig.LOG_ERROR) { + if(TextUtils.isEmpty(logText)){ + Log.i("app", "logText is null"); + }else{ + Log.i("app", logText); + } + } + } +} diff --git a/app/src/main/java/com/rehome/zhdcoa/utils/BitmapUtil.java b/app/src/main/java/com/rehome/zhdcoa/utils/BitmapUtil.java new file mode 100644 index 0000000..976782d --- /dev/null +++ b/app/src/main/java/com/rehome/zhdcoa/utils/BitmapUtil.java @@ -0,0 +1,158 @@ +package com.rehome.zhdcoa.utils; + +import android.content.Context; +import android.content.res.AssetManager; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.ImageFormat; +import android.graphics.Matrix; +import android.graphics.Rect; +import android.graphics.YuvImage; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; + +/** + * @Author yocn + * @Date 2019/8/5 4:11 PM + * @ClassName BitmapUtil + */ +public class BitmapUtil { + public static Bitmap rotateBitmap(Bitmap origin, float rotate) { + if (origin == null) { + return null; + } + int width = origin.getWidth(); + int height = origin.getHeight(); + Matrix matrix = new Matrix(); + matrix.setRotate(rotate); + // 围绕原地进行旋转 + Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false); + if (newBM.equals(origin)) { + return newBM; + } + origin.recycle(); + return newBM; + } + + public static byte[] rotateYUV420Degree90(byte[] data, int imageWidth, int imageHeight) { + byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2]; + // Rotate the Y luma + int i = 0; + for (int x = 0; x < imageWidth; x++) { + for (int y = imageHeight - 1; y >= 0; y--) { + yuv[i] = data[y * imageWidth + x]; + i++; + } + } + // Rotate the U and V color components + i = imageWidth * imageHeight * 3 / 2 - 1; + for (int x = imageWidth - 1; x > 0; x = x - 2) { + for (int y = 0; y < imageHeight / 2; y++) { + yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x]; + i--; + yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)]; + i--; + } + } + return yuv; + } + + public static Bitmap getBitmapImageFromYUV(byte[] data, int width, int height) { + YuvImage yuvimage = new YuvImage(data, ImageFormat.NV21, width, height, null); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + yuvimage.compressToJpeg(new Rect(0, 0, width, height), 80, baos); + byte[] jdata = baos.toByteArray(); + BitmapFactory.Options bitmapFatoryOptions = new BitmapFactory.Options(); + bitmapFatoryOptions.inPreferredConfig = Bitmap.Config.RGB_565; + Bitmap bmp = BitmapFactory.decodeByteArray(jdata, 0, jdata.length, bitmapFatoryOptions); + return bmp; + } + + public static byte[] convertColorToByte(int color[]) { + if (color == null) { + return null; + } + + byte[] data = new byte[color.length * 3]; + for (int i = 0; i < color.length; i++) { + data[i * 3] = (byte) (color[i] >> 16 & 0xff); + data[i * 3 + 1] = (byte) (color[i] >> 8 & 0xff); + data[i * 3 + 2] = (byte) (color[i] & 0xff); + } + + return data; + } + + public static void dumpFile(String fileName, byte[] data) { + FileOutputStream outStream; + try { + outStream = new FileOutputStream(fileName); + } catch (IOException ioe) { + throw new RuntimeException("Unable to create output file " + fileName, ioe); + } + try { + outStream.write(data); + outStream.close(); + } catch (IOException ioe) { + throw new RuntimeException("failed writing data to file " + fileName, ioe); + } + } + + /** + * I420转nv21 + */ + public static byte[] I420Tonv21(byte[] data, int width, int height) { + byte[] ret = new byte[data.length]; + int total = width * height; + + ByteBuffer bufferY = ByteBuffer.wrap(ret, 0, total); + ByteBuffer bufferVU = ByteBuffer.wrap(ret, total, total / 2); + + bufferY.put(data, 0, total); + for (int i = 0; i < total / 4; i += 1) { + bufferVU.put(data[i + total + total / 4]); + bufferVU.put(data[total + i]); + } + + return ret; + } + + public static void saveBitmap(String path, Bitmap bitmap) { + //获取文件 + File file = new File(path); + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file); + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); + fos.flush(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (fos != null) { + fos.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public static Bitmap getBitmapFromAssets(Context context, String path) { + Bitmap bitmap = null; + AssetManager am = context.getResources().getAssets(); + try { + //读取assert 的文图 + InputStream is = am.open(path); + bitmap = BitmapFactory.decodeStream(is); + } catch (Exception e) { + } + return bitmap; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/rehome/zhdcoa/utils/BitmapUtils.java b/app/src/main/java/com/rehome/zhdcoa/utils/BitmapUtils.java new file mode 100644 index 0000000..0b28051 --- /dev/null +++ b/app/src/main/java/com/rehome/zhdcoa/utils/BitmapUtils.java @@ -0,0 +1,117 @@ +package com.rehome.zhdcoa.utils; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.ImageFormat; +import android.graphics.Matrix; +import android.graphics.Rect; +import android.graphics.YuvImage; +import android.hardware.Camera; +import android.util.Base64; + +import java.io.ByteArrayOutputStream; + +/** + * 通用函数 + */ +public class BitmapUtils { + + /** + * byte转为bitmap + * + * @param data 字节流 + * @return bm + */ + public static Bitmap ByteToBitmap(byte[] data, Camera.Size previewSize) { + + Bitmap bm = null; + ByteArrayOutputStream baos = null; + try { + YuvImage yuvimage = new YuvImage(data, ImageFormat.NV21, previewSize.width, previewSize.height, null); + baos = new ByteArrayOutputStream(); + //这里 80 是图片质量,取值范围 0-100,100为品质最高 + yuvimage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 80, baos); + byte[] jdata = baos.toByteArray(); + bm = BitmapFactory.decodeByteArray(jdata, 0, jdata.length);//将data byte型数组转换成bitmap文件 + + // 旋转90度 + + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (baos != null) { + baos.flush(); + baos.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + return bm; + } + + + /** + * base64转为bitmap + * + * @param base64Data + * @return + */ + public static Bitmap Base64ToBitmap(String base64Data) { + byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT); + return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); + } + + + /* + 缩放 指定高度 + */ + public static Bitmap resizeBitmap(Bitmap bm, int ivbWidth, int ivbHeight) { + Bitmap resizeBmp = null; + try { + int width = bm.getWidth(); + int height = bm.getHeight(); + + Matrix matrix = new Matrix(); + + float scaleWidth = ((float) ivbWidth) / width; + float scaleHeight = ((float) ivbHeight) / height; + + matrix.postScale(scaleWidth, scaleHeight); //长和宽放大缩小的比例 + resizeBmp = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true); + + } catch (Exception e) { + e.printStackTrace(); + + } + return resizeBmp; + } + + + /** + * 裁剪图片 + * + * @param bitmap 传入需要裁剪的bitmap + * @return 返回裁剪后的bitmap + */ + public static Bitmap cropBitmap(Bitmap bitmap, int x1, int y1, int x2, int y2) { + if (x1 + x2 + y2 + y1 == 0) { + return null; + } + int cropWidth = x2 - x1; + int cropHeight = y2 - y1; + int crop_x = x1; + int crop_y = y1; + return Bitmap.createBitmap(bitmap, crop_x, crop_y, cropWidth, cropHeight, null, false); + } + + public static byte[] bitmapToByte(Bitmap bitmap) { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); + byte[] byteArray = stream.toByteArray(); + return byteArray; + } + +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_work_risk_list.xml b/app/src/main/res/layout/activity_work_risk_list.xml index 3c7cc21..770e683 100644 --- a/app/src/main/res/layout/activity_work_risk_list.xml +++ b/app/src/main/res/layout/activity_work_risk_list.xml @@ -67,7 +67,6 @@ android:orientation="horizontal"> + android:gravity="center|right" + android:layout_weight="1" + android:textSize="20sp" + android:text="B:" /> + android:layout_weight="1" + android:gravity="center|right" + android:text="C2:" + android:textSize="20sp" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file