Android App开发之位图加工Bitmap中转换位图的像素色彩、裁剪内部区域、利用矩阵变换位图的讲解及实战(附源码和演示)

这篇具有很好参考价值的文章主要介绍了Android App开发之位图加工Bitmap中转换位图的像素色彩、裁剪内部区域、利用矩阵变换位图的讲解及实战(附源码和演示)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

需要图片集和源码请点赞关注收藏后评论区留言~~~

一、转换位图的像素色彩

给图片添加装饰物,只是在局部变换,如果想让图片一边保持轮廓一边改变色彩,就要深入图像的每个像素点,将这些像素点统统采取某种算法修改一番,在像素级别更改图像的话,要先把图片转换成位图对象再进一步加工位图对象,此时用到了位图工具Bitmap 主要方法如下

1:createBitmap 创建一个新位图

2:getPixels 获取位图对象所有点的像素数组

3:setPixels 设置位图对象所有点的像素数组

效果如下 可以将一张图片以多种色彩效果显示出来

 bitmap matrix黑白,Android App,android,android studio,矩阵,java,xml

 bitmap matrix黑白,Android App,android,android studio,矩阵,java,xml

 bitmap matrix黑白,Android App,android,android studio,矩阵,java,xml

 代码如下

Java类

package com.example.picture;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;

import com.example.picture.util.BitmapUtil;

public class BitmapPixelActivity extends AppCompatActivity {
    private ImageView iv_picture; // 声明一个图像视图对象
    private Bitmap mOriginBitmap; // 原始位图

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bitmap_pixel);
        iv_picture = findViewById(R.id.iv_picture);
        mOriginBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.butterfly);
        initColorSpinner(); // 初始化色彩模式下拉框
    }

    // 初始化色彩模式下拉框
    private void initColorSpinner() {
        ArrayAdapter<String> colorAdapter = new ArrayAdapter<>(this,
                R.layout.item_select, colorNameArray);
        Spinner sp_color = findViewById(R.id.sp_color);
        sp_color.setPrompt("请选择色彩模式");
        sp_color.setAdapter(colorAdapter);
        sp_color.setOnItemSelectedListener(new ColorSelectedListener());
        sp_color.setSelection(0);
    }

    private String[] colorNameArray = {"原色", "黑白", "底片", "怀旧", "模糊"};
    class ColorSelectedListener implements AdapterView.OnItemSelectedListener {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            if (arg2 == 0) { // 原色
                iv_picture.setImageBitmap(mOriginBitmap); // 设置图像视图的位图对象
            } else if (arg2 == 1) { // 黑白
                Bitmap bitmap = BitmapUtil.convertBlack(mOriginBitmap); // 转换为黑白效果
                iv_picture.setImageBitmap(bitmap); // 设置图像视图的位图对象
            } else if (arg2 == 2) { // 底片
                Bitmap bitmap = BitmapUtil.convertNegative(mOriginBitmap); // 转换为底片效果
                iv_picture.setImageBitmap(bitmap); // 设置图像视图的位图对象
            } else if (arg2 == 3) { // 怀旧
                Bitmap bitmap = BitmapUtil.convertOld(mOriginBitmap); // 转换为怀旧效果
                iv_picture.setImageBitmap(bitmap); // 设置图像视图的位图对象
            } else if (arg2 == 4) { // 模糊
                Bitmap bitmap = BitmapUtil.convertBlur(mOriginBitmap); // 转换为模糊效果
                iv_picture.setImageBitmap(bitmap); // 设置图像视图的位图对象
            }
        }

        public void onNothingSelected(AdapterView<?> arg0) {}
    }

}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:paddingLeft="5dp"
            android:gravity="center"
            android:text="请选择色彩模式"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <Spinner
            android:id="@+id/sp_color"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:spinnerMode="dialog" />
    </LinearLayout>

    <ImageView
        android:id="@+id/iv_picture"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:src="@drawable/butterfly" />
</LinearLayout>

二、裁剪位图内部区域

createBitmap方法不仅可以创建空白位图,甚至能从原位图上截取一部分下来,裁剪出来的新位图来自原始位图,为了清楚的标记它在原位图的位置,可在图像视图上方覆盖新的图层,然后新图层先画一遍半透明的阴影,再画裁剪的位图部分,观察新老图层就可以看出裁剪的部位 效果如下

可以在下拉框中红选择裁剪不同区域并且保留图片 

bitmap matrix黑白,Android App,android,android studio,矩阵,java,xml

 bitmap matrix黑白,Android App,android,android studio,矩阵,java,xml

 bitmap matrix黑白,Android App,android,android studio,矩阵,java,xml

 代码如下

Java类

package com.example.picture;

import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.picture.util.BitmapUtil;
import com.example.picture.util.DateUtil;
import com.example.picture.widget.CropImageView;

public class BitmapCutActivity extends AppCompatActivity {
    private CropImageView civ_over; // 声明一个裁剪视图对象
    private ImageView iv_old; // 声明一个原始图片的图像视图对象
    private ImageView iv_new; // 声明一个最新图片的图像视图对象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bitmap_cut);
        civ_over = findViewById(R.id.civ_over);
        iv_old = findViewById(R.id.iv_old);
        iv_new = findViewById(R.id.iv_new);
        findViewById(R.id.btn_save_image).setOnClickListener(v -> {
            civ_over.setVisibility(View.GONE);
            Bitmap bitmap = civ_over.getCropBitmap(); // 获取裁剪视图处理后的位图
            iv_new.setImageBitmap(bitmap); // 设置图像视图的位图对象
            // 生成图片文件的保存路径
            String path = String.format("%s/%s.jpg",
                    getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString(),
                    DateUtil.getNowDateTime());
            BitmapUtil.saveImage(path, bitmap); // 把位图保存为图片文件
            BitmapUtil.notifyPhotoAlbum(this, path); // 通知相册来了张新图片
            Toast.makeText(this, "成功保存图片文件:" + path, Toast.LENGTH_SHORT).show();
            initZoneSpinner(); // 初始化裁剪区域下拉框
        });
        iv_old.setDrawingCacheEnabled(true); // 开启位图视图的绘图缓存
        iv_old.setImageResource(R.drawable.butterfly); // 设置图像视图的资源编号
        new Handler(Looper.myLooper()).postDelayed(() -> initZoneSpinner(), 200);
    }

    // 初始化裁剪区域下拉框
    private void initZoneSpinner() {
        ArrayAdapter<String> zoneAdapter = new ArrayAdapter<>(this,
                R.layout.item_select, zoneNameArray);
        Spinner sp_zone = findViewById(R.id.sp_zone);
        sp_zone.setPrompt("请选择裁剪区域");
        sp_zone.setAdapter(zoneAdapter);
        sp_zone.setOnItemSelectedListener(new ZoneSelectedListener());
        sp_zone.setSelection(0);
    }

    private String[] zoneNameArray = {"不裁剪", "中间", "左上角", "右上角", "左下角", "右下角"};
    class ZoneSelectedListener implements AdapterView.OnItemSelectedListener {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            civ_over.setVisibility(arg2==0?View.GONE:View.VISIBLE);
            Bitmap bitmap = iv_old.getDrawingCache(); // 从绘图缓存获取位图对象
            int width = bitmap.getWidth(), height = bitmap.getHeight();
            civ_over.setOrigBitmap(bitmap); // 设置裁剪视图的原始位图
            // 以下依据裁剪区域分别设置裁剪视图的位图边界
            if (arg2 == 1) { // 中间
                civ_over.setBitmapRect(new Rect(width/4, height/4, width/2, height/2));
            } else if (arg2 == 2) { // 左上角
                civ_over.setBitmapRect(new Rect(0, 0, width/2, height/2));
            } else if (arg2 == 3) { // 右上角
                civ_over.setBitmapRect(new Rect(width/2, 0, width/2, height/2));
            } else if (arg2 == 4) { // 左下角
                civ_over.setBitmapRect(new Rect(0, height/2, width/2, height/2));
            } else if (arg2 == 5) { // 右下角
                civ_over.setBitmapRect(new Rect(width/2, height/2, width/2, height/2));
            }
        }

        public void onNothingSelected(AdapterView<?> arg0) {}
    }

}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:paddingLeft="5dp"
            android:gravity="center"
            android:text="请选择裁剪区域"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <Spinner
            android:id="@+id/sp_zone"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:spinnerMode="dialog" />
    </LinearLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="200dp" >

        <ImageView
            android:id="@+id/iv_old"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <com.example.picture.widget.CropImageView
            android:id="@+id/civ_over"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/transparent"
            android:scaleType="fitXY"
            android:visibility="gone" />
    </FrameLayout>

    <Button
        android:id="@+id/btn_save_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="保存图片"
        android:textColor="@color/black"
        android:textSize="17sp" />

    <ImageView
        android:id="@+id/iv_new"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:scaleType="centerInside" />
</LinearLayout>

三、利用矩阵变换位图

可以利用矩阵工具Matrix对图片完成缩放 旋转 平移等变换操作 常用方法如下

postScale 指定横纵坐标两个方向的缩放比率

postRotate  指定旋转角度

postTranslate 指定横纵坐标两个方向的偏移大小

postSkew 指定横纵坐标两个方向的倾斜比例

效果如下 可在下拉框中选择旋转角度以及缩放比例、是否左右反转图像等等 同样可以保存图片

 bitmap matrix黑白,Android App,android,android studio,矩阵,java,xml

 

 bitmap matrix黑白,Android App,android,android studio,矩阵,java,xml

 bitmap matrix黑白,Android App,android,android studio,矩阵,java,xml

 代码如下

Java类

package com.example.picture;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.Spinner;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.picture.util.BitmapUtil;
import com.example.picture.util.DateUtil;
import com.example.picture.widget.BitmapView;

public class BitmapChangeActivity extends AppCompatActivity {
    private BitmapView bv_image; // 声明一个位图视图对象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bitmap_change);
        CheckBox ck_flip = findViewById(R.id.ck_flip);
        bv_image = findViewById(R.id.bv_image);
        ck_flip.setOnCheckedChangeListener((buttonView, isChecked) -> {
            bv_image.flip(); // 左右翻转图像
        });
        findViewById(R.id.btn_save_image).setOnClickListener(v -> {
            Bitmap bitmap = bv_image.getDrawingCache(); // 从绘图缓存获取位图对象
            // 生成图片文件的保存路径
            String path = String.format("%s/%s.jpg",
                    getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString(),
                    DateUtil.getNowDateTime());
            BitmapUtil.saveImage(path, bitmap); // 把位图保存为图片文件
            BitmapUtil.notifyPhotoAlbum(this, path); // 通知相册来了张新图片
            Toast.makeText(this, "成功保存图片文件:" + path, Toast.LENGTH_LONG).show();
        });
        initScaleSpinner(); // 初始化缩放比率下拉框
        initRotateSpinner(); // 初始化旋转角度下拉框
    }

    @Override
    protected void onStart() {
        super.onStart();
        bv_image.setDrawingCacheEnabled(true); // 开启位图视图的绘图缓存
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.butterfly);
        bv_image.setImageBitmap(bitmap); // 设置位图视图的位图对象
    }

    @Override
    protected void onStop() {
        super.onStop();
        bv_image.setDrawingCacheEnabled(false); // 关闭位图视图的绘图缓存
    }

    // 初始化缩放比率下拉框
    private void initScaleSpinner() {
        ArrayAdapter<String> scaleAdapter = new ArrayAdapter<>(this,
                R.layout.item_select, scaleArray);
        Spinner sp_scale = findViewById(R.id.sp_scale);
        sp_scale.setPrompt("请选择缩放比率");
        sp_scale.setAdapter(scaleAdapter);
        sp_scale.setOnItemSelectedListener(new ScaleSelectedListener());
        sp_scale.setSelection(3);
    }

    private String[] scaleArray = {"0.25", "0.5", "0.75", "1.0", "1.5", "2.0", "4.0"};
    class ScaleSelectedListener implements OnItemSelectedListener {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            // 设置缩放比例
            bv_image.setScaleRatio(Float.parseFloat(scaleArray[arg2]), true);
        }

        public void onNothingSelected(AdapterView<?> arg0) {}
    }

    // 初始化旋转角度下拉框
    private void initRotateSpinner() {
        ArrayAdapter<String> rotateAdapter = new ArrayAdapter<>(this,
                R.layout.item_select, rotateArray);
        Spinner sp_rotate = findViewById(R.id.sp_rotate);
        sp_rotate.setPrompt("请选择旋转角度");
        sp_rotate.setAdapter(rotateAdapter);
        sp_rotate.setOnItemSelectedListener(new RotateSelectedListener());
        sp_rotate.setSelection(0);
    }

    private String[] rotateArray = {"0", "45", "90", "135", "180", "225", "270", "315"};
    class RotateSelectedListener implements OnItemSelectedListener {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            // 设置旋转角度
            bv_image.setRotateDegree(Integer.parseInt(rotateArray[arg2]), true);
        }

        public void onNothingSelected(AdapterView<?> arg0) {}
    }

}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="5dp"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="缩放比率"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <Spinner
            android:id="@+id/sp_scale"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:spinnerMode="dialog" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="旋转角度"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <Spinner
            android:id="@+id/sp_rotate"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:spinnerMode="dialog" />

    </LinearLayout>

    <CheckBox
        android:id="@+id/ck_flip"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="是否左右翻转图像"
        android:textColor="@color/black"
        android:textSize="17sp" />

    <com.example.picture.widget.BitmapView
        android:id="@+id/bv_image"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="@color/white" />

    <Button
        android:id="@+id/btn_save_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="保存图片"
        android:textColor="@color/black"
        android:textSize="17sp" />

</LinearLayout>

创作不易 觉得有帮助请点赞关注收藏~~~文章来源地址https://www.toymoban.com/news/detail-639867.html

到了这里,关于Android App开发之位图加工Bitmap中转换位图的像素色彩、裁剪内部区域、利用矩阵变换位图的讲解及实战(附源码和演示)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java中利用BitMap位图实现海量级数据去重

    🏷️ 个人主页 :牵着猫散步的鼠鼠  🏷️ 系列专栏 :Java全栈-专栏 🏷️ 个人学习笔记,若有缺误,欢迎评论区指正 目录 前言 什么是BitMap?有什么用? 基本概念 位图的优势 位图的劣势 BitMap和Int的区别 使用场景 BitMap在Java中的使用 有许多方法可以用来去重,比如使用列

    2024年04月10日
    浏览(41)
  • Android之 Bitmap使用

    一,简介 1.1 Bitmap是一种图片在内存中的表现形式,不管是png,还是jpg最终都是以bitmap的形式显示到控件上面。 Bitmap是一种位图,位图​是点阵图像​或栅格图像,是由称作像素(图片元素)的单个点组成的。这些点可以进行不同的排列和染色以构成图样。当放大位图时,可

    2023年04月25日
    浏览(44)
  • Android JNI Bitmap指定颜色值替换

    2024年02月10日
    浏览(34)
  • Android中本地图片和bitmap的相互转化

    将Bitmap转换为图片 将本地图片转为bitmap 通过流的方式 通过图片路径的方式 该方法直接传文件路径的字符串,即可将指定路径的图片读取到Bitmap对象。 如果是资源文件的话

    2024年02月12日
    浏览(34)
  • bitmap的六种压缩方式,Android图片压缩

    Android中图片是以bitmap形式存在的,那么bitmap所占内存,直接影响到了应用所占内存大小,首先要知道bitmap所占内存大小计算方式: 图片长度 x 图片宽度 x 一个像素点占用的字节数 以下是图片的压缩格式: 其中,A代表透明度;R代表红色;G代表绿色;B代表蓝色。 ALPHA_8 表示

    2024年02月09日
    浏览(48)
  • 【Android】Bitmap图片旋转、缩放、翻转等变换(90/100)

    自定义BitmapChangeView: 工具类: 布局引用: 应用如下: 推荐理由 postman在国内使用已经越来越困难: 1、登录问题严重 2、Mock功能服务基本没法使用 3、版本更新功能已很匮乏 4、某些外力因素导致postman以后能否使用风险较大 出于以上考虑因此笔者自己开发了一款api调试开发工

    2024年02月16日
    浏览(35)
  • Android Drawable转BitmapDrawable再提取Bitmap,Kotlin

    Android Drawable 转化成 Bitmap_zhangphil的博客-CSDN博客 /*Java代码 将Drawable转化为Bitmap */ Bitmap drawableToBitmap(Drawable drawable) { int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); Bitmap bitmap https://blog.csdn.net/zhangphil/article/details/43767535 Android传递Bitmap的两种简单方式及其缺陷

    2024年02月12日
    浏览(33)
  • Android View转换为Bitmap,实现截屏效果

            安卓设备一般都自带截图功能,但是用户体验有不好之处。就是会连带着状态栏📶、🔋、时间日期、其他不必要页面中信息,等等与用户想截屏的内容不符的信息也会被保存下来。通常,截图后用户会再次裁剪一次才能想把真正需求分享出去。         因此,咱们

    2023年04月08日
    浏览(51)
  • Android App开发基础

    App是在手机上运行的一类应用软件,而应用软件依附于操作系统。 智能手机流行的操作系统有两种,分别是安卓手机的Android和苹果手机的iOS。 App开发为Android上的应用开发,Android系统基于Linux内核,但不等于Linux系统,故App应用无法在Linux系统上运行。 Android Studio是谷歌官方

    2024年02月02日
    浏览(39)
  • Android App开发基础(3)——App的设计规范

    本节介绍了App工程的源码设计规范,首先App将看得见的界面设计与看不见的代码逻辑区分开,然后利用XML标记描绘应用界面,同时使用Java代码书写程序逻辑,从而形成App前后端分离的设计规约,有利于提高App集成的灵活性。 手机的功能越来越强大,某种意义上相当于微型电

    2024年02月19日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包