当前位置: 首页 > news >正文

android - JPG图片转换HDR图片,heic格式

android - JPG图片转换HDR图片,heic格式

minSdk 28   //以前是24,heifwriter:heifwriter:1.1.0-alpha01 要求最新28
<!--读写文件-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
android:requestLegacyExternalStorage="true"

//HDR图片(heic)
implementation "androidx.heifwriter:heifwriter:1.1.0-alpha01"//图片选择
implementation 'io.github.lucksiege:pictureselector:v2.7.3-rc08'

package com.example.androidkotlindemo2.hdr;import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.heifwriter.HeifWriter;import com.bumptech.glide.Glide;
import com.example.androidkotlindemo2.R;
import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.entity.LocalMedia;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;/*** 处理HDR(heic)图片* 参考:https://developer.android.com/reference/androidx/heifwriter/HeifWriter*/
public class HDRMainActivity extends AppCompatActivity {private ImageView mImg1;private TextView mTv1;private Button mBtn1;private ImageView mImg2;private TextView mTv2;private Button mBtn2;private LocalMedia imgUrl = null;private Context context = this;private ImageView mImg3;private TextView mTv3;private Button mBtn3;private String destination1;private static final int PERMISSION_REQUEST_CODE = 100;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.hdr_main);mImg1 = findViewById(R.id.img1);mTv1 = findViewById(R.id.tv1);mBtn1 = findViewById(R.id.btn1);mImg2 = findViewById(R.id.img2);mTv2 = findViewById(R.id.tv2);mBtn2 = findViewById(R.id.btn2);mImg3 = findViewById(R.id.img3);mTv3 = findViewById(R.id.tv3);mBtn3 = findViewById(R.id.btn3);findViewById(R.id.btn11).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 检查并申请权限checkAndRequestPermissions();}});mBtn1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//默认有权限checkPic();}});mBtn2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {jpg2Heif();}});mBtn3.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {heif2Jpg();}});}private void checkAndRequestPermissions() {// 需要申请的权限列表String[] permissions = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};List<String> permissionsToRequest = new ArrayList<>();// 检查每个权限是否已授予for (String permission : permissions) {if (ContextCompat.checkSelfPermission(this, permission)!= PackageManager.PERMISSION_GRANTED) {permissionsToRequest.add(permission);}}// 如果有权限需要申请if (!permissionsToRequest.isEmpty()) {ActivityCompat.requestPermissions(this,permissionsToRequest.toArray(new String[0]),PERMISSION_REQUEST_CODE);} else {// 所有权限都已授予onPermissionsGranted();}}@Overridepublic void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == PERMISSION_REQUEST_CODE) {boolean allGranted = true;// 检查所有权限是否都被授予for (int grantResult : grantResults) {if (grantResult != PackageManager.PERMISSION_GRANTED) {allGranted = false;break;}}if (allGranted) {onPermissionsGranted();} else {onPermissionsDenied();}}}private void onPermissionsGranted() {// 权限已授予,执行相关操作Toast.makeText(this, "存储权限已授予", Toast.LENGTH_SHORT).show();// 这里可以调用需要权限的方法//accessExternalStorage();}private void onPermissionsDenied() {// 处理权限被拒绝的情况if (shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) ||shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {// 用户拒绝了权限,但没有选择"不再询问"showPermissionRationaleDialog();} else {// 用户拒绝了权限并选择了"不再询问"showGoToSettingsDialog();}}private void showPermissionRationaleDialog() {new AlertDialog.Builder(this).setTitle("需要存储权限").setMessage("应用需要存储权限来读取和保存文件").setPositiveButton("确定", (dialog, which) -> {// 再次请求权限checkAndRequestPermissions();}).setNegativeButton("取消", null).show();}private void showGoToSettingsDialog() {new AlertDialog.Builder(this).setTitle("权限被永久拒绝").setMessage("您已永久拒绝存储权限,请在设置中手动授予权限").setPositiveButton("去设置", (dialog, which) -> {// 跳转到应用设置页面Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);Uri uri = Uri.fromParts("package", getPackageName(), null);intent.setData(uri);startActivity(intent);}).setNegativeButton("取消", null).show();}private void heif2Jpg() {// Using HEIFWriter from Google// https://developer.android.com/reference/androidx/heifwriter/HeifWriter/* val heif = HEIF()// Step 1: Load fileheif.load("HEIC.heic")// Step 2: Check type of HEIF format, cause it have many types: Still Image, Grid Image ... (Apple is using GridImage type for that format)when (heif.primaryImage) {is GridImageItem -> {}is IdentityImageItem -> {}is OverlayImageItem -> {}is HEVCImageItem -> {}is AVCImageItem -> {}}// Step 3: In-case this is GridImageItem// Get size width, heightval originalWidth = primaryImage.size.widthval originalHeight = primaryImage.size.height// Getting original rotation degree of Original Image fileval rotationDegree =(heif.itemProperties.findLast { it is RotateProperty } as? RotateProperty)?.rotation?.value?: 0// Apple is using 48 tiles and join to 1 images, parse of its and then convert its to HEVC bitstream by FFMPEGfor (rowIndex in 0 until primaryImage.rowCount) {for (columnIndex in 0 until primaryImage.columnCount) {// Getting the tile image based column / rowval hevcImageItem = primaryImage.getImage(columnIndex, rowIndex) as HEVCImageItem// Getting decoder config and then using mobile-ffmpeg to write to HEVC bitstream in local storage.....}// After getting 48 tiles as bitstream files, join its and merge into 1 files by ffmpeg.....// Loading Color profiles and attach it.....// Convert BitStream to JPG.JPEG.PNG file by FFMPEG....// Loading Exifdata and attach it.....// Delete temp files and finish convert.}*/}private void jpg2Heif() {Bitmap bitmap;bitmap = BitmapFactory.decodeFile(imgUrl.getRealPath());Log.e("cxx", "获取bitmap成功");int imageHeight = bitmap.getHeight();int imageWidth = bitmap.getWidth();Log.e("cxx", "获取宽高");
//        destination1 = getExternalFilesDir("/").getAbsolutePath() + "/photo2.heic";Random random = new Random();int fileName2 = Integer.valueOf(random.nextInt(Integer.MAX_VALUE));String destinations = Environment.getExternalStorageDirectory() + "/Pictures/"+fileName2+".heic";Log.e("cxx", "生成路径:" + destinations);try {HeifWriter heifWriter = new HeifWriter.Builder(destinations, imageWidth, imageHeight, HeifWriter.INPUT_MODE_BITMAP).setQuality(90).build();heifWriter.start();heifWriter.addBitmap(bitmap);heifWriter.stop(0);heifWriter.close();Log.e("cxx", "生成完毕:");long mbSize = getFileSize(destinations);mTv2.setText(destinations+"--大小:"+mbSize);Glide.with(context).load(destinations).into(mImg2);Log.e("cxx", "加载完毕");File f = new File(destinations);// 通知图库更新Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);Uri uri = Uri.fromFile(f);intent.setData(uri);context.sendBroadcast(intent);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}private void checkPic() {//maxSelectNum()选择图片的数量PictureSelector.create(this).openGallery(PictureMimeType.ofImage()).imageEngine(GlideEngine.createGlideEngine()).maxSelectNum(1).forResult(PictureConfig.CHOOSE_REQUEST);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_OK) {switch (requestCode) {case PictureConfig.CHOOSE_REQUEST: {List<LocalMedia> result = PictureSelector.obtainMultipleResult(data);if (result.size() <= 0) {return;}imgUrl = result.get(0);long mbSize = getFileSize(imgUrl.getRealPath());mTv1.setText(imgUrl.getFileName() + "--大小:" + mbSize+"mb");Glide.with(this).load(result.get(0).getPath()).into(mImg1);}}}}private long getFileSize(String realPath) {File file = new File(realPath);long size = 0;long mbSize = 0;FileInputStream fis = null;try {fis = new FileInputStream(file);size = fis.available();mbSize = size/1024/1024;} catch (IOException e) {e.printStackTrace();}return  mbSize;}}

package com.example.androidkotlindemo2.hdr;import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;public class ImageLoaderUtils {public static boolean assertValidRequest(Context context) {if (context instanceof Activity) {Activity activity = (Activity) context;return !isDestroy(activity);} else if (context instanceof ContextWrapper){ContextWrapper contextWrapper = (ContextWrapper) context;if (contextWrapper.getBaseContext() instanceof Activity){Activity activity = (Activity) contextWrapper.getBaseContext();return !isDestroy(activity);}}return true;}private static boolean isDestroy(Activity activity) {if (activity == null) {return true;}return activity.isFinishing() || activity.isDestroyed();}}

package com.example.androidkotlindemo2.hdr;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.BitmapImageViewTarget;
import com.bumptech.glide.request.target.ImageViewTarget;import com.example.androidkotlindemo2.R;
import com.luck.picture.lib.engine.ImageEngine;
import com.luck.picture.lib.listener.OnImageCompleteCallback;
import com.luck.picture.lib.tools.MediaUtils;
import com.luck.picture.lib.widget.longimage.ImageSource;
import com.luck.picture.lib.widget.longimage.ImageViewState;
import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView;public class GlideEngine implements ImageEngine {/*** 加载图片** @param context* @param url* @param imageView*/@Overridepublic void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) {if (!ImageLoaderUtils.assertValidRequest(context)) {return;}Glide.with(context).load(url).into(imageView);}/*** 加载网络图片适配长图方案* # 注意:此方法只有加载网络图片才会回调** @param context* @param url* @param imageView* @param longImageView* @param callback      网络图片加载回调监听 {link after version 2.5.1 Please use the #OnImageCompleteCallback#}*/@Overridepublic void loadImage(@NonNull Context context, @NonNull String url,@NonNull ImageView imageView,SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) {if (!ImageLoaderUtils.assertValidRequest(context)) {return;}Glide.with(context).asBitmap().load(url).into(new ImageViewTarget<Bitmap>(imageView) {@Overridepublic void onLoadStarted(@Nullable Drawable placeholder) {super.onLoadStarted(placeholder);if (callback != null) {callback.onShowLoading();}}@Overridepublic void onLoadFailed(@Nullable Drawable errorDrawable) {super.onLoadFailed(errorDrawable);if (callback != null) {callback.onHideLoading();}}@Overrideprotected void setResource(@Nullable Bitmap resource) {if (callback != null) {callback.onHideLoading();}if (resource != null) {boolean eqLongImage = MediaUtils.isLongImg(resource.getWidth(),resource.getHeight());longImageView.setVisibility(eqLongImage ? View.VISIBLE : View.GONE);imageView.setVisibility(eqLongImage ? View.GONE : View.VISIBLE);if (eqLongImage) {// 加载长图longImageView.setQuickScaleEnabled(true);longImageView.setZoomEnabled(true);longImageView.setDoubleTapZoomDuration(100);longImageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_CROP);longImageView.setDoubleTapZoomDpi(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER);longImageView.setImage(ImageSource.cachedBitmap(resource),new ImageViewState(0, new PointF(0, 0), 0));} else {// 普通图片imageView.setImageBitmap(resource);}}}});}/*** 加载网络图片适配长图方案* # 注意:此方法只有加载网络图片才会回调** @param context* @param url* @param imageView* @param longImageView* @ 已废弃*/@Overridepublic void loadImage(@NonNull Context context, @NonNull String url,@NonNull ImageView imageView,SubsamplingScaleImageView longImageView) {if (!ImageLoaderUtils.assertValidRequest(context)) {return;}Glide.with(context).asBitmap().load(url).into(new ImageViewTarget<Bitmap>(imageView) {@Overrideprotected void setResource(@Nullable Bitmap resource) {if (resource != null) {boolean eqLongImage = MediaUtils.isLongImg(resource.getWidth(),resource.getHeight());longImageView.setVisibility(eqLongImage ? View.VISIBLE : View.GONE);imageView.setVisibility(eqLongImage ? View.GONE : View.VISIBLE);if (eqLongImage) {// 加载长图longImageView.setQuickScaleEnabled(true);longImageView.setZoomEnabled(true);longImageView.setDoubleTapZoomDuration(100);longImageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_CROP);longImageView.setDoubleTapZoomDpi(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER);longImageView.setImage(ImageSource.cachedBitmap(resource),new ImageViewState(0, new PointF(0, 0), 0));} else {// 普通图片imageView.setImageBitmap(resource);}}}});}/*** 加载相册目录** @param context   上下文* @param url       图片路径* @param imageView 承载图片ImageView*/@Overridepublic void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) {if (!ImageLoaderUtils.assertValidRequest(context)) {return;}Glide.with(context).asBitmap().load(url).override(180, 180).centerCrop().sizeMultiplier(0.5f).placeholder(R.drawable.ic_launcher_background).into(new BitmapImageViewTarget(imageView) {@Overrideprotected void setResource(Bitmap resource) {RoundedBitmapDrawable circularBitmapDrawable =RoundedBitmapDrawableFactory.create(context.getResources(), resource);circularBitmapDrawable.setCornerRadius(8);imageView.setImageDrawable(circularBitmapDrawable);}});}/*** 加载gif** @param context   上下文* @param url       图片路径* @param imageView 承载图片ImageView*/@Overridepublic void loadAsGifImage(@NonNull Context context, @NonNull String url,@NonNull ImageView imageView) {if (!ImageLoaderUtils.assertValidRequest(context)) {return;}Glide.with(context).asGif().load(url).into(imageView);}/*** 加载图片列表图片** @param context   上下文* @param url       图片路径* @param imageView 承载图片ImageView*/@Overridepublic void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) {if (!ImageLoaderUtils.assertValidRequest(context)) {return;}Glide.with(context).load(url).override(200, 200).centerCrop().placeholder(R.drawable.ic_launcher_background).into(imageView);}private GlideEngine() {}private static GlideEngine instance;public static GlideEngine createGlideEngine() {if (null == instance) {synchronized (GlideEngine.class) {if (null == instance) {instance = new GlideEngine();}}}return instance;}
}

hdr_main.xml布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools">
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><ImageViewandroid:layout_width="120dp"android:layout_height="120dp"android:layout_gravity="center_horizontal"android:id="@+id/img1"android:layout_marginTop="20dp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="名字:无"android:layout_marginTop="20dp"android:id="@+id/tv1"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="选择照片"android:layout_gravity="center_horizontal"android:layout_marginTop="20dp"android:id="@+id/btn1"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="选择照片- 先授权"android:layout_gravity="center_horizontal"android:layout_marginTop="20dp"android:textColor="@color/red"android:textSize="22sp"android:id="@+id/btn11"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><ImageViewandroid:layout_width="120dp"android:layout_height="120dp"android:layout_gravity="center_horizontal"android:id="@+id/img2"android:layout_marginTop="20dp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="名字:无"android:layout_marginTop="20dp"android:id="@+id/tv2"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="转换格式成heif - heic - HDR图片 "android:textAllCaps="false"android:layout_gravity="center_horizontal"android:layout_marginTop="20dp"android:id="@+id/btn2"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><ImageViewandroid:layout_width="120dp"android:layout_height="120dp"android:layout_gravity="center_horizontal"android:id="@+id/img3"android:layout_marginTop="20dp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="名字:无"android:layout_marginTop="20dp"android:id="@+id/tv3"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="heif转jpg"android:layout_gravity="center_horizontal"android:layout_marginTop="20dp"android:id="@+id/btn3"/></LinearLayout></LinearLayout>
</androidx.core.widget.NestedScrollView>

http://www.dtcms.com/a/503156.html

相关文章:

  • 【C语言】文件操作(附源码与图片)
  • Vue-Router4使用详解(结合Vue3)
  • 免费做做网站网站建设优化方法 s
  • 图书馆理论与建设网站北京工程建设监理协会网站
  • postman 调用接口设置全局变量
  • Lua协程coroutine库用法
  • 若依字典原理---后端
  • SpringBoot 接入 Prometheus + Grafana
  • 自己有网站怎么做优化实时热榜
  • 基于SpringBoot的“基于数据安全的旅游民宿租赁系统”的设计与实现(源码+数据库+文档+PPT)
  • 海宁公司做网站wordpress编辑器存内容
  • 旅游管理系统|基于SpringBoot和Vue的旅游管理系统(源码+数据库+文档)
  • DAQ系统混合方案与设计模式详解
  • 【Linux系统编程】3. Linux基本指令(下)
  • sql练习-5
  • 做网站审批号必须要wix做网站的建议
  • YAML的Value表示
  • 如何在Gitee和GitHub上部署SSH公钥
  • 成都高新网站建设美图秀秀在线制作
  • Flutter Isolate的使用
  • 从 JDK 8 到 JDK 23:HotSpot 垃圾回收器全景演进与深度剖析
  • 深圳网站建设jm3q网站是公司域名是个人可以吗
  • 【深度学习新浪潮】多模态大模型在图像理解领域的技术进展与实践
  • wordpress 分类菜单高亮外贸seo软件
  • 百度面试题解析:Zookeeper、ArrayList、生产者消费者模型及多线程(二)
  • excel绘制折线图
  • 数据结构(c++版):二叉树的实现
  • 厦门手机网站建设wordpress mkv格式
  • spiderdemo题解系列——第2篇:请求头检测挑战(第1题)
  • 数据事件及数据查询——东方财富掘金量化速成学习(python)