Android App开发实战项目之大头贴App功能实现(附源码和演示 简单易上手)

news2024/12/23 8:47:49

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

一、需求描述

大头贴App有两个特征,第一个是头要大,拿来一张照片后把人像区域裁剪出来,这样新图片里的人头才会比较大,第二个是在周围贴上装饰物,而且装饰物还能随时更换,这样一副人像可以变换出许多张大头贴(类似于现在拍照APP的环境变换功能)

二、功能分析

  就人像剪裁功能而言,首先适当变换图片,把人像区域调整到屏幕中央,以便后续的裁剪操作,这些图片变换操作包括平移图片,旋转图片,水平反转图片等等。调整好人像位置以后,再来裁剪指定的人像区域,为了方便观察待裁剪区域和其余的图片区域,可将待裁剪区域高亮显示,同时暗色显示其余的图片区域。

  就人像装饰功能而言,可用于装饰的物品包括一段文字,图片标志,相框背景等等。待装饰的人像图片由前一步的人像裁剪而来,装饰完成的人像图片需要支持保存到存储卡,从而实现大头贴的多次加工操作

下面简单介绍一下源码之间的关系 便于理解

1:PortraitActivity  采集头像的活动页面 从原始图片裁剪指定的人像区域

2:PurikuraActivity  制作大头贴的活动页面,给采集来的头像添加各种装饰

采集头像的时候,先把裁剪后的头像保存为图片文件,再将图片文件路径返回给制作页面

三、效果展示 

采集头像页面如下 可以选择左右反转上下移动等操作选择图片的不同位置 

 

 装饰图像效果如下

可以加上不同的背景和装饰文字

 

 

 

 

 四、代码

采集图像类代码如下

package com.example.picture;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

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

public class PortraitActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {
    private final static String TAG = "PortraitActivity";
    private int COMBINE_CODE = 4; // 既可拍照获得现场图片、也可在相册挑选已有图片的请求码
    private BitmapView bv_photo; // 声明一个位图视图对象
    private CropImageView civ_photo; // 声明一个裁剪视图对象
    private LinearLayout ll_adjust; // 声明一个线性布局对象
    private SeekBar sb_scale; // 声明一个拖动条对象
    private SeekBar sb_horizontal; // 声明一个拖动条对象
    private SeekBar sb_vertical; // 声明一个拖动条对象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_portrait);
        TextView tv_title = findViewById(R.id.tv_title);
        tv_title.setText("采集头像");
        TextView tv_option = findViewById(R.id.tv_option);
        tv_option.setText("确定");
        tv_option.setOnClickListener(v -> finishCollect());
        bv_photo = findViewById(R.id.bv_photo);
        civ_photo = findViewById(R.id.civ_photo);
        ll_adjust = findViewById(R.id.ll_adjust);
        findViewById(R.id.btn_combine).setOnClickListener(v -> openSelectDialog());
        CheckBox ck_flip = findViewById(R.id.ck_flip);
        ck_flip.setOnCheckedChangeListener((buttonView, isChecked) -> {
            bv_photo.flip(); // 左右翻转图像
            civ_photo.flip(); // 左右翻转图像
        });
        sb_scale = findViewById(R.id.sb_scale);
        sb_horizontal = findViewById(R.id.sb_horizontal);
        sb_vertical = findViewById(R.id.sb_vertical);
        sb_scale.setOnSeekBarChangeListener(this);
        sb_horizontal.setOnSeekBarChangeListener(this);
        sb_vertical.setOnSeekBarChangeListener(this);
    }

    // 结束头像采集
    private void finishCollect() {
        if (civ_photo.getCropBitmap() == null) {
            Toast.makeText(this, "请先选好头像图片", Toast.LENGTH_SHORT).show();
            return;
        }
        // 生成图片文件的保存路径
        String path = String.format("%s/%s.jpg",
                getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString(),
                DateUtil.getNowDateTime());
        BitmapUtil.saveImage(path, civ_photo.getCropBitmap()); // 把位图保存为图片文件
        BitmapUtil.notifyPhotoAlbum(this, path); // 通知相册来了张新图片
        Intent intent = new Intent(); // 创建一个新意图
        intent.putExtra("pic_path", path);
        setResult(Activity.RESULT_OK, intent); // 携带意图返回前一个页面
        finish(); // 关闭当前页面
    }

    // 打开选择对话框(要拍照还是去相册)
    private void openSelectDialog() {
        // 声明相机的拍照行为
        Intent photoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        Intent[] intentArray = new Intent[] { photoIntent };
        // 声明相册的打开行为
        Intent albumIntent = new Intent(Intent.ACTION_GET_CONTENT);
        albumIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false); // 是否允许多选
        albumIntent.setType("image/*"); // 类型为图像
        // 容纳相机和相册在内的选择意图
        Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
        chooserIntent.putExtra(Intent.EXTRA_TITLE, "请拍照或选择图片");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
        chooserIntent.putExtra(Intent.EXTRA_INTENT, albumIntent);
        // 创建封装好标题的选择器意图
        Intent chooser = Intent.createChooser(chooserIntent, "选择图片");
        // 在页面底部弹出多种选择方式的列表对话框
        startActivityForResult(chooser, COMBINE_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        if (resultCode == RESULT_OK && requestCode == COMBINE_CODE) { // 从组合选择返回
            if (intent.getData() != null) { // 从相册选择一张照片
                Uri uri = intent.getData(); // 获得已选择照片的路径对象
                // 根据指定图片的uri,获得自动缩小后的位图对象
                Bitmap bitmap = BitmapUtil.getAutoZoomImage(this, uri);
                showPicture(bitmap); // 显示已选择的图片
            } else if (intent.getExtras() != null) { // 拍照的缩略图
                Object obj = intent.getExtras().get("data");
                if (obj instanceof Bitmap) { // 属于位图类型
                    Bitmap bitmap = (Bitmap) obj; // 强制转成位图对象
                    showPicture(bitmap); // 显示已选择的图片
                }
            }
        }
    }

    // 显示已选择的图片
    private void showPicture(Bitmap origin) {
        bv_photo.setDrawingCacheEnabled(true); // 开启位图视图的绘图缓存
        bv_photo.setImageBitmap(origin); // 设置图像视图的位图对象
        ll_adjust.setVisibility(View.VISIBLE);
        sb_scale.setProgress(30); // 设置拖动条的当前进度
        sb_horizontal.setProgress(50); // 设置拖动条的当前进度
        sb_vertical.setProgress(50); // 设置拖动条的当前进度
        Bitmap bitmap = bv_photo.getDrawingCache(); // 从绘图缓存获取位图对象
        if (bitmap == null) {
            return;
        }
        int width = bitmap.getWidth(), height = bitmap.getHeight();
        civ_photo.setOrigBitmap(bitmap); // 设置裁剪视图的原始位图
        // 设置位图的矩形边界
        civ_photo.setBitmapRect(new Rect(width/8, height/8, width/4*3, height/4*3));
        bv_photo.setDrawingCacheEnabled(false); // 关闭位图视图的绘图缓存
    }

    // 刷新图像展示
    private void refreshImage() {
        Bitmap bitmap = bv_photo.getDrawingCache(); // 从绘图缓存获取位图对象
        civ_photo.setOrigBitmap(bitmap); // 设置裁剪视图的原始位图
        civ_photo.setBitmapRect(civ_photo.getBitmapRect()); // 设置裁剪视图的位图边界
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        bv_photo.setDrawingCacheEnabled(true); // 开启位图视图的绘图缓存
        if (seekBar.getId() == R.id.sb_scale) {
            bv_photo.setScaleRatio(progress/33f, true); // 设置位图视图的缩放比率
        } else if (seekBar.getId()==R.id.sb_horizontal || seekBar.getId()==R.id.sb_vertical) {
            int viewWidth = bv_photo.getMeasuredWidth(); // 获取视图的实际宽度
            int viewHeight = bv_photo.getMeasuredHeight(); // 获取视图的实际高度
            int offsetX = (int) ((sb_horizontal.getProgress()-50)/50f*viewWidth);
            int offsetY = (int) ((sb_vertical.getProgress()-50)/50f*viewHeight);
            Log.d(TAG, "viewWidth="+viewWidth+", offsetX="+offsetX+", viewHeight="+viewHeight+", offsetY="+offsetY);
            bv_photo.setOffset(offsetX, offsetY, true); // 设置位图视图的偏移距离
        }
        refreshImage(); // 刷新图像展示
        bv_photo.setDrawingCacheEnabled(false); // 关闭位图视图的绘图缓存
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {}

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {}
}

装饰图像类代码如下

package com.example.picture;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.net.Uri;
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.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

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

public class PurikuraActivity extends AppCompatActivity {
    private final static String TAG = "PurikuraActivity";
    private int COLLECT_CODE = 14; // 采集头像的请求码
    private DecorateImageView div_photo; // 声明一个装饰视图对象
    private EditText et_text; // 声明一个编辑框对象
    private boolean haveCollected = false; // 是否已采集头像

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_purikura);
        findViewById(R.id.iv_back).setOnClickListener(v -> finish());
        TextView tv_title = findViewById(R.id.tv_title);
        tv_title.setText("大头贴");
        TextView tv_option = findViewById(R.id.tv_option);
        tv_option.setText("保存");
        tv_option.setOnClickListener(v -> savePurikura());
        div_photo = findViewById(R.id.div_photo);
        et_text = findViewById(R.id.et_text);
        findViewById(R.id.btn_text).setOnClickListener(v -> {
            String text = et_text.getText().toString();
            div_photo.showText(text, false); // 显示装饰文本
        });
        findViewById(R.id.btn_collect).setOnClickListener(v -> {
            // 下面跳到头像采集页面
            Intent intent = new Intent(this, PortraitActivity.class);
            startActivityForResult(intent, COLLECT_CODE);
        });
        initLogoSpinner(); // 初始化标志图片下拉框
        initFrameSpinner(); // 初始化相框种类下拉框

    }

    // 保存加工好的大头贴图片
    private void savePurikura() {
        if (!haveCollected) {
            Toast.makeText(this, "请先采集头像图片", Toast.LENGTH_SHORT).show();
            return;
        }
        div_photo.setDrawingCacheEnabled(true); // 开启装饰视图的绘图缓存
        Bitmap bitmap = div_photo.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_SHORT).show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        if (resultCode == RESULT_OK && requestCode == COLLECT_CODE) { // 从采集头像返回
            String pic_path = intent.getStringExtra("pic_path");
            div_photo.setImageURI(Uri.parse(pic_path)); // 设置图像视图的路径对象
            haveCollected = true;
        }
    }

    // 初始化标志图片下拉框
    private void initLogoSpinner() {
        ArrayAdapter<String> logoAdapter = new ArrayAdapter<>(this,
                R.layout.item_select, logoNameArray);
        Spinner sp_logo = findViewById(R.id.sp_logo);
        sp_logo.setPrompt("请选择标志图片");
        sp_logo.setAdapter(logoAdapter);
        sp_logo.setOnItemSelectedListener(new LogoSelectedListener());
        sp_logo.setSelection(0);
    }

    private String[] logoNameArray = {"无标志", "春之兰花", "夏之荷花", "秋之菊花", "冬之梅花"};
    class LogoSelectedListener implements AdapterView.OnItemSelectedListener {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            Bitmap bitmap = null;
            if (arg2 == 1) { // 春之兰花
                bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flower_orchid);
            } else if (arg2 == 2) { // 夏之荷花
                bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flower_lotus);
            } else if (arg2 == 3) { // 秋之菊花
                bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flower_chrysanthemum);
            } else if (arg2 == 4) { // 冬之梅花
                bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flower_plum);
            }
            div_photo.showLogo(bitmap, false); // 显示装饰标志
        }

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

    // 初始化相框种类下拉框
    private void initFrameSpinner() {
        ArrayAdapter<String> frameAdapter = new ArrayAdapter<>(this,
                R.layout.item_select, frameNameArray);
        Spinner sp_frame = findViewById(R.id.sp_frame);
        sp_frame.setPrompt("请选择相框种类");
        sp_frame.setAdapter(frameAdapter);
        sp_frame.setOnItemSelectedListener(new FrameSelectedListener());
        sp_frame.setSelection(0);
    }

    private String[] frameNameArray = {"无相框", "长方相框", "椭圆相框", "稻草相框", "爱心相框"};
    class FrameSelectedListener implements AdapterView.OnItemSelectedListener {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            Bitmap bitmap = null;
            if (arg2 == 1) { // 长方相框
                bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.photo_frame1);
            } else if (arg2 == 2) { // 椭圆相框
                bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.photo_frame2);
            } else if (arg2 == 3) { // 稻草相框
                bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.photo_frame3);
            } else if (arg2 == 4) { // 爱心相框
                bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.photo_frame4);
            }
            div_photo.showFrame(bitmap, false); // 显示装饰相框
        }

        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">

    <include layout="@layout/title_purikura" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="270dp" >

        <com.example.picture.widget.BitmapView
            android:id="@+id/bv_photo"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white"
            android:scaleType="centerCrop" />

        <com.example.picture.widget.CropImageView
            android:id="@+id/civ_photo"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>

    <Button
        android:id="@+id/btn_combine"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="拍照或从相册选取"
        android:textColor="@color/black"
        android:textSize="17sp" />

    <LinearLayout
        android:id="@+id/ll_adjust"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical"
        android:visibility="invisible">

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

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:layout_margin="10dp"
            android:gravity="center"
            android:orientation="horizontal">

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

            <SeekBar
                android:id="@+id/sb_scale"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:max="100"
                android:progress="30" />

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

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:layout_margin="10dp"
            android:gravity="center"
            android:orientation="horizontal">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="左移"
                android:textColor="@color/black"
                android:textSize="17sp" />

            <SeekBar
                android:id="@+id/sb_horizontal"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:max="100"
                android:progress="50" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="右移"
                android:textColor="@color/black"
                android:textSize="17sp" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:layout_margin="10dp"
            android:gravity="center"
            android:orientation="horizontal">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="上移"
                android:textColor="@color/black"
                android:textSize="17sp" />

            <SeekBar
                android:id="@+id/sb_vertical"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:max="100"
                android:progress="50" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="下移"
                android:textColor="@color/black"
                android:textSize="17sp" />

        </LinearLayout>
    </LinearLayout>

</LinearLayout>

创作不易 觉得有帮助请点赞关注收藏~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/12108.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring】——7、@Import注解给容器中快速导入一个组件

&#x1f4eb;作者简介&#xff1a;zhz小白 公众号&#xff1a;小白的Java进阶之路 专业技能&#xff1a; 1、Java基础&#xff0c;并精通多线程的开发&#xff0c;熟悉JVM原理 2、熟悉Java基础&#xff0c;并精通多线程的开发&#xff0c;熟悉JVM原理&#xff0c;具备⼀定的线…

Ubuntu下关于cuda和cudnn 报错 现象及解决方案

详细流程&#xff1a;1、现象2、探索&#xff08;可跳过&#xff09;3、完美解决&#xff08;真实原因&#xff09;3.1 查看当前cuda版本3.2电脑有多个cuda版本&#xff0c;通过改变软链接改变指向3.3 写入系统环境&#xff1a;1、现象 啊这,重启丢失了个啥触摸的驱动&#xff…

Java并发 - (并发基础)

Java并发 - (并发基础) 1、什么是共享资源 堆是被所有线程共享的一块内存区域。在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例 Java中几乎所有的对象实例都在这里分配内存。方法区与堆一样&#xff0c;也是各个线程共享的一块内存区域&#xff0c;它用于存储已被…

Linux实用操作-----快捷键的使用(收藏系列)

推荐教程&#xff1a;Linux零基础快速入门到精通 ctrl c 强制停止 •Linux某些程序的运行&#xff0c;如果想要强制停止它&#xff0c;可以使用快捷键ctrl c •命令输入错误&#xff0c;也可以通过快捷键ctrl c&#xff0c;退出当前输入&#xff0c;重新输入 ctrl d 退出…

注意论文投稿风险,现投期刊会不会成为预警期刊呢?

中科院发布《国际预警期刊名单》 2021年12月31日&#xff0c;中国科学院文献情报中心期刊分区表团队发布《国际期刊预警名单&#xff08;试行&#xff09;》&#xff0c;用以提醒科研人员审慎选择成果发表平台&#xff0c;提示出版机构强化期刊质量管理。截至目前&#xff0c;…

Vue 实现拖拽模块(二)自定义拖拽组件位置

上文介绍了 拖拽添加组件 的简单实现&#xff0c;本文将继续给大家分享如何自定义拖拽组件位置的简单实现&#xff0c;文中通过示例代码介绍&#xff0c;感兴趣的小伙伴们可以了解一下 本文主要介绍了 Vue自定义拖拽组件位置的简单实现&#xff0c;具体如下&#xff1a; 效果图…

高空抛物检测方案设计(使用SOM进行轨迹分类)

文章目录前言一、技术方案介绍1.方案设计图2.流程介绍3.说明二、实际检测1.摄像头的安装2.实际检测三、误报解决误报事件1&#xff1a;飞鸟误报事件2&#xff1a;树叶误报事件3&#xff1a;被子解决方案轨迹展示原始轨迹SOM分类结果总结前言 高空抛物检测的关键是方案的设计&a…

MATLAB 绘图合集:分类散点图gscatter

本文主要介绍如何依据数据类别同时呈现数据散点图。 目录 说明 例子 使用默认设置绘图 使用数据类别来画图 使用多组数据类别来画图 创建并调整散点图 说明 gscatter(x,y,g) 创建 和 的散点图x&#xff0c;y按 分组g。输入x和 y是相同大小的向量。 例子 gscatter(x,y,g,c…

Jekyll 语句语法、功能的实现方法和结构介绍小手册

本文很长&#xff0c;建议使用侧边栏进行跳转。 本文虽然按照由浅入深的顺序介绍了 Jekyll 的语句语法和功能结构&#xff0c;但是主要用于快速查询一些 Jekyll 语句、功能的实现方法和结构介绍。 如果你想&#xff1a; 了解查看一些常用的 Jekyll 的相关命令和选项还请查看&…

第六章第一节:图的基本概念和存储及基本操作

文章目录1. 图的基本概念1.1 图逻辑结构的应用1.2 无向图&#xff0c;有向图1.3 简单图&#xff0c;多重图1.4 顶点的度&#xff0c;入度和出度1.5 顶点和顶点的关系描述1.6 连通图&#xff0c;强连通图1.7 研究图的局部——子图1.8 生成树1.9 生成森林1.10 边的权&#xff0c;…

手机怎么实现图片转文字操作?学会这三招就够了

随着互联网不断发展&#xff0c;我们手机的功能越来越丰富&#xff0c;现在基本上只需要一部手机&#xff0c;就能满足我们的多样化需求。比如想要提取书本中的文字&#xff0c;我们不需要再手动输入&#xff0c;只要将文字内容拍照下来&#xff0c;利用一些软件来提取图片中的…

【深度学习】argparse模块一些学习心得体会(2)| parser.parse_known_args() |位置参数 可选参数

文章目录前言一、位置参数和可选参数二、parser.parse_known_args()前言 之前我们写了一期命令行模块的使用介绍&#xff0c;但是依然有很多语法是没有介绍到的&#xff1a;比如parser.parse_known_args()这样的命令。这样的命令大量出现在各大开源项目中&#xff0c;今天我就…

外汇天眼:官网虚假宣传受到多重监管!FCA率先发出警告!

11月16日&#xff0c;英国金融行为监管局( FCA )发出最新警告&#xff0c;提示投资者警惕与 Trade Top FX 这家未经授权的公司打交道。 FCA警告称&#xff1a;Trade Top FX 在未经我们授权的情况下在英国提供金融服务或产品&#xff0c;如果一旦遭受资金损失&#xff0c;您将无…

Word处理控件Aspose.Words功能演示:在 Python 中比较两个 Word 文档

在各种情况下执行 Word 文档的比较以确定差异。各种在线工具允许您比较 Word 文档&#xff0c;但是&#xff0c;您可能需要在应用程序中实现比较功能。为实现它&#xff0c;本文展示了如何在 Python 中比较两个 Word 文档。 Aspose.Words for . Python 最新下载&#xff08;qu…

子容器在启动期间失败

​ 遇错&#xff1a; 今天遇到一个Bug&#xff1a;A child container failed during start 中文翻译为&#xff1a;子容器在启动期间失败 事情是这样的&#xff0c;一开始我在做案例的时候使用的tomcat是本地集成的&#xff0c;项目能正常运行&#xff1b; 后来我将tomcat的…

Dopamine-PEG-N3,DOPA-PEG-azide,水溶性PEG试剂供应

1、名称 英文&#xff1a;Dopamine-PEG-N3&#xff0c;DOPA-PEG-azide 中文&#xff1a;多巴胺-聚乙二醇-叠氮 2、CAS编号&#xff1a;N/A 3、所属分类&#xff1a;Azide PEG Dopamine PEG 4、分子量&#xff1a;可定制&#xff0c;有2k、5k、3.4k、10k、20k、1k 5、质量…

【salesforce】Lightning Web Component Study Log —— Part 2

持续学习中… 文章目录版本管理V1.0.01. The Lightning Web Components Model1.1 Web演变1.2 LWC1.3Aura和LWC的互用性2. Creating Lightning Web Components2.1 在VSCode定义一个LWC组件2.2 文件构成2.3 客户端-服务端体系结构2.4 基础UI组件-JS2.5 基础UI组件-HTML2.6 基础UI…

艾美捷PEG-2000 DMG解决方案

艾美捷PEG-2000 DMG英文全名1,2-dimyristoyl-rac-glycero-3-methoxypolyethylene glycol-2000&#xff0c;中文名可对应翻译为二肉豆蔻酰甘油-聚乙二醇2000。它的分子式为C122H242O50&#xff0c;分子量2509.2&#xff08;平均值&#xff09;&#xff0c;代表结构如下&#xff…

数字IC手撕代码-XX公司笔试真题(串并转换控制)

前言&#xff1a; 本专栏旨在记录高频笔面试手撕代码题&#xff0c;以备数字前端秋招&#xff0c;本专栏所有文章提供原理分析、代码及波形&#xff0c;所有代码均经过本人验证。 目录如下&#xff1a; 1.数字IC手撕代码-分频器&#xff08;任意偶数分频&#xff09; 2.数字…

JetsonNano部署yolo5 c++ onnx

编译OpenCV最新4.5.x版本 Jetson Nano自带的OpenCV版本比较低&#xff0c;Jetpack4.6对应的OpenCV版本为4.1的 而OpenCV当前最新版本已经到了4.5跟4.6了&#xff0c;4.5.x中OpenCV DNN支持了很多新的模型推理跟新的特性都无法在OpenCV4.1上演示&#xff0c;所以我决定从源码编…