当前位置: 首页 > 编程日记 > 正文

图片基础知识梳理(3) BitmapBitmapFactory 解析

一、概述

今天这篇文章我们来了解一下两个类:

  • Bitmap
  • BitmapFactory

二、Bitmap

2.1 创建Bitmap

通过Bitmap的源码,我们可以看到它内部提供了很多.createBitmap(xxx)的静态方法,我们可以通过这些方法来获得一个Bitmap

上述的方法最终可以分为以下三类:

  • 通过一个已有的Bitmap创建
  • 创建一个空的Bitmap
  • 创建一个新的Bitmap,该Bitmap每个像素点的颜色通过一个colors[]数组指定。

下面,我们来看一下这三类方法对于Bitmap的生产过程:

第一类

    public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,Matrix m, boolean filter) {checkXYSign(x, y);checkWidthHeight(width, height);//新的bitmap范围不能大于原始的bitmapif (x + width > source.getWidth()) {throw new IllegalArgumentException("x + width must be <= bitmap.width()");}if (y + height > source.getHeight()) {throw new IllegalArgumentException("y + height must be <= bitmap.height()");}//如果满足下面这些条件,那么直接返回原始的bitmapif (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() &&height == source.getHeight() && (m == null || m.isIdentity())) {return source;}int neww = width;int newh = height;Canvas canvas = new Canvas();Bitmap bitmap;Paint paint;//生成bitmap对应区域Rect srcR = new Rect(x, y, x + width, y + height);//原始bitmap对应区域RectF dstR = new RectF(0, 0, width, height);Config newConfig = Config.ARGB_8888;//获得原始bitmap的configfinal Config config = source.getConfig();// GIF files generate null configs, assume ARGB_8888if (config != null) {switch (config) {case RGB_565:newConfig = Config.RGB_565;break;case ALPHA_8:newConfig = Config.ALPHA_8;break;//noinspection deprecationcase ARGB_4444:case ARGB_8888:default:newConfig = Config.ARGB_8888;break;}}//如果不需要变换,那么创建一个空的bitmap.if (m == null || m.isIdentity()) {bitmap = createBitmap(neww, newh, newConfig, source.hasAlpha());paint = null;   // not needed} else {//根据Matrix,对原始的bitmap进行一些变换操作.final boolean transformed = !m.rectStaysRect();RectF deviceR = new RectF();m.mapRect(deviceR, dstR);neww = Math.round(deviceR.width());newh = Math.round(deviceR.height());bitmap = createBitmap(neww, newh, transformed ? Config.ARGB_8888 : newConfig,transformed || source.hasAlpha());canvas.translate(-deviceR.left, -deviceR.top);canvas.concat(m);paint = new Paint();paint.setFilterBitmap(filter);if (transformed) {paint.setAntiAlias(true);}}//返回bitmap的这些属性和原始bitmap相同bitmap.mDensity = source.mDensity;bitmap.setHasAlpha(source.hasAlpha());bitmap.setPremultiplied(source.mRequestPremultiplied);//设置canvas对应的bitmap为返回的bitmapcanvas.setBitmap(bitmap);//通过canvas把原始的bitmap绘制上去.canvas.drawBitmap(source, srcR, dstR, paint);//重新置为空.canvas.setBitmap(null);return bitmap;}
复制代码
  • 方法作用:返回原始的Bitmap中一个不可改变的子集,返回的Bitmap有可能是原始的Bitmap(原始的Bitmap不可改变,并且大小和请求的新的Bitmap大小和原来一样),也有可能是复制出来的,它和原始的Bitmapdensity相同。
  • 参数说明:
  • source:原始的Bitmap
  • x, y:在原始的Bitmap中的起始坐标。
  • width, height:返回的Bitmap的宽高,如果超过了原始Bitmap的范围,那么会抛出异常。
  • mMatrix类型,表示需要的变换
  • filter:是否需要优化,只有当m不只有平移操作时才去进行。

第二类

    private static Bitmap createBitmap(DisplayMetrics display, int width, int height, Config config, boolean hasAlpha) {if (width <= 0 || height <= 0) {throw new IllegalArgumentException("width and height must be > 0");}Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true);if (display != null) {bm.mDensity = display.densityDpi;}bm.setHasAlpha(hasAlpha);if (config == Config.ARGB_8888 && !hasAlpha) {nativeErase(bm.mNativePtr, 0xff000000);}return bm;}
复制代码
  • 方法作用:返回一个可变的bitmap,它的density由传入的DisplayMetrics指定。
  • 参数说明:
  • displayBitmap将要被绘制的Display metrics
  • width, heightbitmap的宽高
  • config:配置信息,对应ARGB_8888那些。
  • hasAlpha:如果bitmap的属性是ARGB_8888,那么这个标志为可以用来把bitmap标志为透明,它会把bitmap中的黑色像素转换为透明。

第三类

    public static Bitmap createBitmap(DisplayMetrics display, int colors[],int offset, int stride, int width, int height, Config config) {checkWidthHeight(width, height);if (Math.abs(stride) < width) {throw new IllegalArgumentException("abs(stride) must be >= width");}int lastScanline = offset + (height - 1) * stride;int length = colors.length;if (offset < 0 || (offset + width > length) || lastScanline < 0 ||(lastScanline + width > length)) {throw new ArrayIndexOutOfBoundsException();}if (width <= 0 || height <= 0) {throw new IllegalArgumentException("width and height must be > 0");}Bitmap bm = nativeCreate(colors, offset, stride, width, height,config.nativeInt, false);if (display != null) {bm.mDensity = display.densityDpi;}return bm;}
复制代码
  • 方法作用:返回一个不可变的bitmap对象,它的长宽由width/height指定,每个像素点的颜色通过colos[]数组得到,初始的density来自于DisplayMetrics
  • 方法参数:
  • displayBitmap将要被绘制的Display metrics
  • colors:用来初始化像素点的颜色
  • offset:第一个像素点的颜色在数组当中跳过的个数。
  • stride:两行之间需要跳过的颜色个数。
  • width/height:宽高。
  • config:对应ARGB_8888那些。

2.2 压缩bitmap

    public boolean compress(CompressFormat format, int quality, OutputStream stream) {checkRecycled("Can't compress a recycled bitmap");// do explicit check before calling the native methodif (stream == null) {throw new NullPointerException();}if (quality < 0 || quality > 100) {throw new IllegalArgumentException("quality must be 0..100");}Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "Bitmap.compress");boolean result = nativeCompress(mNativePtr, format.nativeInt,quality, stream, new byte[WORKING_COMPRESS_STORAGE]);Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);return result;}
复制代码
  • 方法作用:把当前这个bitmap的压缩版本写入到某个输出流当中,如果返回true,那么这个bitmap可以被BitmapFactory.decodeStream()恢复。需要注意的是,并不是所有的bitmap都支持所有的格式,因此,通过BitmapFactory恢复回来的bitmap有可能和原来不同。
  • 方法参数:
  • CompressFormat是一个枚举类型,它的值有JPEG/PNG/WEBP
  • quality对应0-100
  • stream则是压缩后结果的输出流。

2.3 回收bitmap

    public void recycle() {if (!mRecycled && mNativePtr != 0) {if (nativeRecycle(mNativePtr)) {// return value indicates whether native pixel object was actually recycled.// false indicates that it is still in use at the native level and these// objects should not be collected now. They will be collected later when the// Bitmap itself is collected.mBuffer = null;mNinePatchChunk = null;}mRecycled = true;}}
复制代码

recycle方法主要做几件事:

  • 释放和这个bitmap关联的native对象
  • 清除像素数据mBuffer的引用,但是这一过程不是同步的,它只是将引用置为空,等待垃圾回收器将它回收。
  • 在调用这个方法之后,mRecycled标志位就为true,之后如果再调用bitmap的方法,那么很有可能发生异常。
  • 一般情况下,我们不需要手动调用这个方法,因为当这个bitmap不被引用时,垃圾回收器就会自动回收它所占用的内存。

2.4 获取Bitmap所占内存

  • getAllocationByteCount() 返回存储这个bitmap对象所需要的内存,当我们对bitmap所占内存区域进行复用的时候,这个函数的返回结果可能要大于getByteCount的值,否则,它和getByteCount的值是相同的。 这个值,在bitmap整个生命周期之内都不会改变。
    public final int getAllocationByteCount() {if (mBuffer == null) {return getByteCount();}return mBuffer.length;}
复制代码
  • getByteCount 表示存储bitmap像素所需要的最小字节,自从4.4之后,这个就不能用来确定bitmap占用的内存了,需要用getAllocationByteCount
    public final int getByteCount() {// int result permits bitmaps up to 46,340 x 46,340return getRowBytes() * getHeight();}
复制代码

2.5 获取缩放后大小

我们可以通过上面这六个方法获得缩放后的宽高,它们的原理就是传入一个目标的density,然后和当前bitmapdensity进行比较,然后算出一个缩放的倍数,在和原来的大小相乘。目标density的来源有以下三个:

  • 直接传入
  • Canvasdensity
  • DisplayMetricsdensity

计算的规则为:

    static public int scaleFromDensity(int size, int sdensity, int tdensity) {if (sdensity == DENSITY_NONE || tdensity == DENSITY_NONE || sdensity == tdensity) {return size;}// Scale by tdensity / sdensity, rounding up.return ((size * tdensity) + (sdensity >> 1)) / sdensity;}
复制代码

三、BitmapFactory

BitmapFactory用来从多种不同的来源获得Bitmap

  • 文件、文件描述符
  • 资源文件Resource
  • byte[]数组
  • 输入流InputStream

3.1 BitmapFactory.Options

  • Bitmap inBitmap 如果给Options设置了这个Bitmap,那么在通过这个Options解码的时候,解码方法返回的bitmap会尝试复用这个Options中的bitmap,如果不能复用,那么解码方法会返回null,并抛出异常,它要求复用的bitmap是可变的。 在4.4以后,只要求新申请的bitmapgetByteCount()小于等于Options中的bitmapgetAllocationByteCount()就可以。 在4.4以前,格式必须是jpeg/png,并且要求两个bitmap相同并且inSampleSize1
  • boolean inJustDecodeBounds 如果设为true,那么解码方法的返回值null,但是它会设置outXXX的值,这样调用者就可以在不用解码整张图片的前提下查询到这个bitmap的长宽。
  • int inSampleSize 对原来的图片进行采样,如果inSampleSize4,那么图片的长宽会缩短为原来的1/4,这样就可以减少bitmap占用的内存。
  • Bitmap.Config inPreferredConfig 图片解码的格式要求。
  • 缩放相关的标志:inScaledinDensityinTargetDensityinScreenDensity 首先,只有在inScaledtrue的时候,缩放的机制才会生效,这个值默认是true的。
  • inDensity 我们先讨论一下inDensity,当我们没有给density赋值的时候,系统会给我们初始化它:
        //如果没有设置densityif (opts.inDensity == 0 && value != null) {final int density = value.density; //这里的TypeValue会根据存放文件夹的不同而不同.if (density == TypedValue.DENSITY_DEFAULT) {opts.inDensity = DisplayMetrics.DENSITY_DEFAULT; //如果density为0,那么把density设置为160.} else if (density != TypedValue.DENSITY_NONE) {opts.inDensity = density; //否则,设置为value中的density.}}
复制代码
  • inTargetDensity 再来看一下inTargetDensity,它得到的就是屏幕的density.
        if (opts.inTargetDensity == 0 && res != null) {opts.inTargetDensity = res.getDisplayMetrics().densityDpi;}
复制代码
  • inScreenDensity 最后inScreenDensity没有被赋予默认值,也就是说它为0,如果我们期望图片不要被缩放,那么就要给它设置为手机的density

这三者的关系是:inDensity不为0并且inTargetDensity不为0inDensityinScreenDensity不相等时,会对图片进行缩放,缩放倍数为inTargetDensity/inDensity

这样说可能比较抽象,我们举一个实际的例子,假如我们的手机的density320dpi的,那么inTargetDensity就等于320,这时候我们把某张图片资源放在了drawable-xxxhpi下,那么inDensity的值就为640,我们没有设置inScreenDensity,那么它的默认值是0,这时候满足:

inDensity != 0 && inTargetDensity != 0 && inDensity != inScreenDensity
复制代码

图片就会进行缩放,缩放的倍数就为320/640,也就是说最终得到的bitmap的长宽是原来的一半。

  • outXXX 这个返回的结果和inJustDecodeBounds有关,如果inJustDecodeBoundstrue,那么返回的是没有经过缩放的大小,如果为false,那么就是缩放后的大小。

3.2 获取bitmap方法

下面是BitmapFactory提供的方法:

所有的获取bitmap最终都是调用了一下四个方法Native方法其中之一,可以看到它可以从这些来源读取:

  • file
  • byte[]
  • InputStream

其中有个需要注意的是Rect,这是一个传入的值,在读取资源完毕后,它会写入读取资源的padding,如果没有那么为[-1, -1, -1,- 1],而如果返回的bitmap为空,那么传入的值不会改变。

四、Bitmap的转换方法

public class BitmapConvertUtils {public static Bitmap fromResourceIdAutoScale(Resources resources, int resourceId, BitmapFactory.Options options) {return BitmapFactory.decodeResource(resources, resourceId, options);}public static Bitmap fromResourceIdNotScale(Resources resources, int resourceId, Rect rect, BitmapFactory.Options options) {InputStream resourceStream = null;Bitmap bitmap = null;try {resourceStream = resources.openRawResource(resourceId);bitmap = BitmapFactory.decodeStream(resourceStream, rect, options);} catch (Exception e) {e.printStackTrace();} finally {try {if (resourceStream != null) {resourceStream.close();}} catch (Exception e) {e.printStackTrace();}}return bitmap;}public static Bitmap fromAssert(Context context, String assertFilePath, Rect rect, BitmapFactory.Options options) {Bitmap bitmap = null;InputStream assertStream = null;AssetManager assetManager = context.getAssets();try {assertStream = assetManager.open(assertFilePath);bitmap = BitmapFactory.decodeStream(assertStream, rect, options);} catch (Exception e) {e.printStackTrace();} finally {try {if (assertStream != null) {assertStream.close();}} catch (Exception e) {e.printStackTrace();}}return bitmap;}public static Bitmap fromByteArray(byte[] byteArray, int offset, int length, BitmapFactory.Options options) {return BitmapFactory.decodeByteArray(byteArray, offset, length, options);}public static Bitmap fromFile(String filePath, BitmapFactory.Options options) {return BitmapFactory.decodeFile(filePath, options);}public static Bitmap fromDrawable(Drawable drawable) {int width = drawable.getIntrinsicWidth();int height = drawable.getIntrinsicHeight();Bitmap bitmap = Bitmap.createBitmap(width, height, drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);if (bitmap != null) {Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, width, height);drawable.draw(canvas);return bitmap;}return null;}public static Bitmap fromView(View view) {view.clearFocus();view.setPressed(false);boolean willNotCache = view.willNotCacheDrawing();view.setWillNotCacheDrawing(false);int color = view.getDrawingCacheBackgroundColor();view.setDrawingCacheBackgroundColor(color);if (color != 0) {view.destroyDrawingCache();}view.buildDrawingCache();Bitmap cacheBitmap = view.getDrawingCache();if (cacheBitmap == null) {return null;}Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);view.destroyDrawingCache();view.setWillNotCacheDrawing(willNotCache);view.setDrawingCacheBackgroundColor(color);return bitmap;}public static Bitmap fromInputStream(InputStream inputStream) {return BitmapFactory.decodeStream(inputStream);}public static byte[] toByteArray(Bitmap bitmap, Bitmap.CompressFormat format, int quality) {byte[] bytes = null;ByteArrayOutputStream outputStream = new ByteArrayOutputStream();bitmap.compress(format, quality, outputStream);bytes = outputStream.toByteArray();try {outputStream.close();} catch (Exception e) {e.printStackTrace();}return bytes;}public static Drawable toDrawable(Resources resources, Bitmap bitmap) {return new BitmapDrawable(resources, bitmap);}public static void toFile(Bitmap bitmap, Bitmap.CompressFormat format, int quality, String path) {FileOutputStream fileOutputStream = null;try {fileOutputStream = new FileOutputStream(path);bitmap.compress(format, quality, fileOutputStream);} catch (Exception e) {e.printStackTrace();} finally {try {if (fileOutputStream != null) {fileOutputStream.close();}} catch (Exception e) {e.printStackTrace();}}}}
复制代码

相关文章:

电路实验1-电容充放电

转载于:https://www.cnblogs.com/cutepig/archive/2013/01/17/2865289.html

【直播】陈信达:零基础计算机视觉之机器学习基础

零基础计算机视觉之机器学习基础 直播信息 分享嘉宾&#xff1a;陈信达&#xff0c;Datawhale成员&#xff0c;上海科技大学硕士。 直播时间&#xff1a;2021年07月30日 20:00 直播内容&#xff1a; 线性回归与指针读数识别逻辑回归原理与代码选讲人工神经网络与Fashion-MN…

UI培训分享:如何成为一名优秀的UI设计师

UI设计师在工作岗位中也是分等级的&#xff0c;如何成为一名优秀的UI设计师在如今的职业发展中是非常有必要的&#xff0c;各行各业都在内卷中&#xff0c;那么如何成为一名优秀的UI设计师呢?来看看下面的详细介绍。 UI培训分享&#xff1a;如何成为一名优秀的UI设计师? 好UI…

POJ 2418 Hardwood Species(trie 树)

题目链接 开始想用map的&#xff0c;字典序不会搞&#xff0c;还是老老实实的用trie树把。好久没写了&#xff0c;忘得差不多了。 1 #include <iostream>2 #include <cstdio>3 #include <cstdlib>4 #include <cstring>5 #include <map>6 #includ…

白盒测试实践-任务完成

这次的白盒测试实践已经圆满完成&#xff0c;每个人都分配到了相应的任务&#xff0c;并对各自的任务进行了具体的落实。 分配情况如下&#xff1a; 阶段任务名称任务负责人阶段一测试用例清单安秀芳阶段二静态评审罗阳刚、周成阶段三自动化静态检查滕怡天阶段四基于JUnit的单元…

【第23周复盘】懒癌犯了,拖到今天!

「青少年编程竞赛交流群」已成立&#xff08;适合6至18周岁的青少年&#xff09;&#xff0c;公众号后台回复【Scratch】或【Python】&#xff0c;即可进入。如果加入了之前的社群不需要重复加入。 微信后台回复“资料下载”可获取以往学习的材料&#xff08;视频、代码、文档&…

软件测试培训分享:软件测试的职业发展方向有哪些

很多人都觉得软件测试在互联网行业入门是比较轻松的&#xff0c;对于如此轻松的行业&#xff0c;它所在的职业发展前景怎么样呢?软件测试的职业发展方向有哪些呢?本期软件测试培训分享内容请看以下详细介绍。 软件测试的职业发展方向有哪些?职业的选择对于现在的年轻人来说相…

【青少年编程】【三级】换装

「青少年编程竞赛交流群」已成立&#xff08;适合6至18周岁的青少年&#xff09;&#xff0c;公众号后台回复【Scratch】或【Python】&#xff0c;即可进入。如果加入了之前的社群不需要重复加入。 微信后台回复“资料下载”可获取以往学习的材料&#xff08;视频、代码、文档&…

转程序员,都去写一写前端代码吧

转自: http://www.oschina.net/news/36972/programmer-write-frond-end-code 你可以认为我是一个极端的人&#xff0c;就像有许多人专注于自己的领域而不屑于其它“肤浅”的工作范畴一样。比如我见过不少认为做portal没有技术含量的 判定&#xff0c;做工程都是充满苦逼行为的言…

大数据之公开数据的价值

2019独角兽企业重金招聘Python工程师标准>>> 大数据按照访问权限来划分&#xff0c;可分为私有数据和公开数据。私有数据不是每个人都能够自由访问调用的数据&#xff0c;例如银行交易记录、抵押信息、医疗数据、通讯数据、电商交易数据等等。私有数据因其私有性&am…

UI培训教程分享:Ui设计的细节规范有哪些需要注意?

在职场中&#xff0c;有很多UI设计师是零经验的&#xff0c;都是刚学会技术就来入职的&#xff0c;与经验丰富的其他成员来说&#xff0c;新人一定要提高自己的工作能力&#xff0c;本篇UI培训教程为大家分享的是Ui设计的细节规范有哪些需要注意?希望能给大家在工作中带来帮助…

linux 安装输入法

IBus IBus是一个框架&#xff0c;支持多种输入法 IBus输入法安装和设置 IBus是一个框架&#xff0c;支持多种输入法。安裝IBus框架&#xff1a; 在终端输入: sudo apt-get install ibus ibus-clutter ibus-gtk ibus-gtk3 ibus-qt4 启用IBus框架&#xff1a; 在终端输入: im-swi…

记录在Spring-Boot中使用Fegin调用RESTfull的PATCH方法设置

使用了ZooKeeper&#xff0c;设置 spring.cloud.zookeeper.dependency.headers.enabledfalse 参考&#xff1a; https://github.com/spring-cloud/spring-cloud-netflix/issues/2550#issuecomment-353230054 http://blog.csdn.net/menggudaoke/article/details/77884674>如有…

【青少年编程】【四级】词语接龙

「青少年编程竞赛交流群」已成立&#xff08;适合6至18周岁的青少年&#xff09;&#xff0c;公众号后台回复【Scratch】或【Python】&#xff0c;即可进入。如果加入了之前的社群不需要重复加入。 微信后台回复“资料下载”可获取以往学习的材料&#xff08;视频、代码、文档&…

Python培训教程分享:有哪些值得使用的爬虫开源项目?

相信很多同学在学习Python技术的时候&#xff0c;都有学习到Python爬虫技术&#xff0c;爬虫技术在各大互联网公司都是非常常见的&#xff0c;可以帮助我们获取各种网站的信息&#xff0c;比如微博、B站、知乎等&#xff0c;本篇Python培训教程分享为大家整理了几个Python爬虫项…

apue学习之文件IO第二部分

学习apue课程已经有一个多月了&#xff0c;有很多知识点需要自己去总结: 下面是主要的几个函数的介绍: 1-stat()函数是获得文件的主要信息。在linux当中主要以一个结构体来保存文件的信息&#xff0c;其中每一个字段都代表着文件的一个信息量: struct stat {dev_t st_dev; …

LSGO软件技术团队招新

团队招新 LSGO软件技术团队&#xff08;Dreamtech算法组&#xff09;成立于2010年09月&#xff0c;团队主要从事地理信息系统、管理信息系统、计算机视觉等领域的应用开发&#xff0c;团队同时具有培养学生的重要职能&#xff0c;毕业学生分布在IBM、百度、阿里、腾讯、京东、…

java一个月日历

项目需要&#xff0c;获取当天之后的30天&#xff0c;并提示星期几&#xff08;周几&#xff09;&#xff0c;写了一个工具类 /** 计算日期时间author shijing2015年8月10日下午2:16:09param date 传入的需要计算的日期param timeWay 计算方式&#xff08;年、月、周、日&#…

UI培训分享:学UI设计需要知道哪些事情?

很多同学都想要学习UI设计技术&#xff0c;因为UI设计行业的发展前景非常不错&#xff0c;通过成为一名合格的UI设计师能够够更好的进入到互联网行业&#xff0c;那么学UI设计需要知道哪些事情呢?先来看看下面的详细介绍。 UI培训分享&#xff1a;学UI设计需要知道哪些事情? …

Web开发的那点事--数据持久层常用功能

CSDN博客不再经常更新&#xff0c;更多优质文章请来 粉丝联盟网 FansUnion.cn! (FansUnion) 数据持久层--4类功能 1.增加 增加一条记录-实体&#xff08;有关联&#xff0c;没有关联&#xff09; 2.修改 修改一个字段 修改多个字段 修改哪一列或哪些列&#xff1a;wher…

Dotfuscator代码混淆工具的使用

关于Dotfuscator&#xff0c;VS自带了一个社区版的源代码保护工具&#xff0c;不过它只有基本的混淆命名的功能。专业版功能很多&#xff0c;可以混淆流程&#xff0c;密字符串&#xff0c;加入水印&#xff0c;程序签名等。 工具/原料 Dotfuscator Professional Edition 4.9方…

【青少年编程(第24周)】Python-Turtle组队学习结营!

2021年08月01日&#xff08;周日&#xff09;晚20:00我们在青少年编程竞赛交流群开展了第二十四次直播活动。我们直播活动的主要内容如下&#xff1a; 首先&#xff0c;我们奖励了上周测试超过60分的小朋友。 其次&#xff0c;讲解了上次测试中小朋友们做错的题目。 最后&…

参加完Python培训后有哪些就业方向

很多学习Python技术的同学都是为了后面能够找到一个好的工作&#xff0c;对于大家来说了解了Python的就业方向&#xff0c;后面就可以根据自己的能力来选择对应的工作岗位了&#xff0c;那么下面小编就为大家详细的介绍一下参加完Python培训后有哪些就业方向? 参加完Python培训…

June:Datawhale开源学习小程序升级啦!

1. 开源学习小程序的使用 我们通过七个视频来介绍如何使用Datawhale开源学习小程序。 第一个视频&#xff1a;完善个人信息报名 组队学习报名前&#xff0c;请大家完善个人信息的填写&#xff0c;便于结课后证书发放。 切换到组队学习页面&#xff0c;进入当前营期&#xf…

mybatis-错误记录java.lang.ExceptionInInitializerError

今天刚学习mybatis&#xff0c;遇到了一个错误&#xff0c;纠结了半天的时间&#xff0c;所以将发现的问题和解决得方法写一下。 错误信息如下&#xff1a; java.lang.ExceptionInInitializerErrorat com.ibatis.po.TestSysArea.testInsert(TestSysArea.java:31)at sun.reflect…

解决ScrollView嵌套ListView高度的问题

2019独角兽企业重金招聘Python工程师标准>>> public static void setListViewHeight(ListView listView) {ListAdapter listAdapter listView.getAdapter();int totalHeight 0;for (int i 0; i < listAdapter.getCount(); i) {View listItem listAdapter.get…

UI培训教程分享:UI设计如何确定设计风格

在UI设计工作岗位中&#xff0c;进行设计工作的时候&#xff0c;UI设计师门需要对整体的设计要素进行把控&#xff0c;这样才能设计出优秀的设计作品&#xff0c;本期小编为大家介绍的UI培训教程就是关于UI设计如何确定设计风格&#xff0c;希望以下内容能够给大家带来帮助。 U…

32位汇编寄存器及汇编指令

32位CPU所含有的寄存器有&#xff1a; 4个数据寄存器(EAX、EBX、ECX和EDX)2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP) 6个段寄存器(ES、CS、SS、DS、FS和GS)1个指令指针寄存器(EIP) 1个标志寄存器(EFlags) 1、数据寄存器数据寄存器主要用来保存操作数和运算结果等…

RPC-client异步收发核心细节?

通过上篇文章的介绍&#xff0c;知道了要实施微服务&#xff0c;首先要搞定RPC框架&#xff0c;RPC框架分为客户端部分与服务端部分。 RPC-client的部分又分为&#xff1a; &#xff08;1&#xff09;序列化反序列化的部分&#xff08;上图中的1、4&#xff09; &#xff08;2&…

【青少年编程】【三级】病毒传染模拟程序

「青少年编程竞赛交流群」已成立&#xff08;适合6至18周岁的青少年&#xff09;&#xff0c;公众号后台回复【Scratch】或【Python】&#xff0c;即可进入。如果加入了之前的社群不需要重复加入。 微信后台回复“资料下载”可获取以往学习的材料&#xff08;视频、代码、文档&…