NV21、NV12、YV12、RGB、YUV、RGBA、RGBX8888等图像色彩编码格式区别

简介: NV21、NV12、YV12、RGB、YUV、RGBA、RGBX8888都是常见的图像颜色编码格式,它们之间的主要区别在于色彩空间和数据排列方式。

常用图像颜色编码格式

NV21、NV12、YV12、RGB、YUV、RGBA、RGBX8888都是常见的图像颜色编码格式,它们之间的主要区别在于色彩空间和数据排列方式。


1.NV21:NV21是Android系统使用的一种图像颜色编码格式,它采用的是YUV 4:2:0的采样方式,意味着垂直方向上每两个像素采样一次,水平方向上每个像素采样两次。NV21的Y分量是亮度信息,V和U分量是色度信息(分别代表饱和度和色调)。


2.NV12:NV12是一种用于视频编解码的颜色编码格式,它同样采用了YUV 4:2:0的采样方式。NV12的Y分量是亮度信息,V和U分量也是色度信息。不同的是,与NV21不同的是,NV12的Y、V、U三个分量分别采用了不同的采样率,即垂直方向上每两个像素采样一次,水平方向上每隔一个像素采样一次。


3.YV12:YV12是一种常见的视频编解码格式,它同样采用了YUV 4:2:0的采样方式。YV12的Y分量是亮度信息,V和U分量也是色度信息。不同的是,YV12的Y、V、U三个分量分别采用了不同的采样率,即垂直方向上每两个像素采样一次,水平方向上每隔一个像素采样一次。


4.RGB:RGB是一种常见的颜色编码格式,它采用红、绿、蓝三种颜色组成图像。RGB的R、G、B三个分量分别表示红色、绿色和蓝色的强度。RGB图像中的每个像素都需要三个值来表示颜色,因此它的数据排列方式是按照红、绿、蓝的顺序排列。


5.RGBA:RGBA是一种常见的颜色编码格式,与RGB类似,但它额外包含了一个Alpha通道,用于表示像素的透明度。RGBA的R、G、B三个分量分别表示红色、绿色和蓝色的强度,A表示透明度。


6.RGBX8888:RGBX8888是一种常见的颜色编码格式,与RGBA类似,但它将像素的颜色和透明度信息都存储在32位整型中。RGBX8888的R、G、B三个分量分别表示红色、绿色和蓝色的强度,X表示透明度。


7.YUY2:YUY2是一种常见的视频编解码格式,它采用YUV 4:2:2的采样方式。YUY2的Y分量是亮度信息,U和V分量是色度信息(分别代表饱和度和色调)。YUY2在水平方向上每隔一个像素采样一次,垂直方向上每隔两个像素采样一次。


8.UYVY:UYVY是一种常见的视频编解码格式,它同样采用YUV 4:2:2的采样方式。UYVY的Y分量是亮度信息,U和V分量是色度信息(分别代表饱和度和色调)。UYVY在水平方向上每隔一个像素采样一次,垂直方向上每隔两个像素采样一次。

如何对接数据类型

本文以Android平台RTMP直播推送模块为例,video图像编码前接口设计如下:

YUV420888

/*
     * SmartPublisherJniV2.java
     * SmartPublisherJniV2
     *
     * Author: daniusdk.com
     * Created by DaniuLive on 2015/09/20.
     */
    /**
   * 投递层YUV420888图像, 专门为android.media.Image的android.graphics.ImageFormat.YUV_420_888格式提供的接口
   *
   * @param index: 层索引, 必须大于等于0
   *
   * @param left: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param top: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param y_plane: 对应android.media.Image.Plane[0].getBuffer()
   *
   * @param y_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
   *
   * @param y_row_stride: 对应android.media.Image.Plane[0].getRowStride()
   *
   * @param u_plane: android.media.Image.Plane[1].getBuffer()
   *
   * @param u_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
   *
   * @param u_row_stride: android.media.Image.Plane[1].getRowStride()
   *
   * @param v_plane: 对应android.media.Image.Plane[2].getBuffer()
   *
   * @param v_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
   *
   * @param v_row_stride: 对应android.media.Image.Plane[2].getRowStride()
   *
   * @param uv_pixel_stride: 对应android.media.Image.Plane[1].getPixelStride()
   *
   * @param width: width, 必须大于1, 且必须是偶数
   *
   * @param height: height, 必须大于1, 且必须是偶数
   *
   * @param  is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
   *
   * @param  is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
   *
   * @param  scale_width: 缩放宽,必须是偶数, 0或负数不缩放
   *
   * @param  scale_height: 缩放高, 必须是偶数, 0或负数不缩放
   *
   * @param  scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
   *
   * @param  rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
   *
   * @return {0} if successful
   */
  public native int PostLayerImageYUV420888ByteBuffer(long handle, int index, int left, int top,
                             ByteBuffer y_plane, int y_offset, int y_row_stride,
                               ByteBuffer u_plane, int u_offset, int u_row_stride,
                             ByteBuffer v_plane, int v_offset, int v_row_stride, int uv_pixel_stride,
                             int width, int height, int is_vertical_flip,  int is_horizontal_flip,
                             int scale_width,  int scale_height, int scale_filter_mode,
                               int rotation_degree);

YV12

YV12的数据接口,主要是用于第三方的设备对接居多,这个接口的u_stride, v_stride分别是(width+1)/2,如果出来的数据需要旋转,通过rotation_degree来控制旋转角度即可。

/**
     * YV12数据接口
     *
     * @param data: YV12 data
     *
     * @param width: 图像宽
     *
     * @param height: 图像高
     *
     * @param y_stride:  y面步长
     *
     * @param v_stride: v面步长
     *
     * @param u_stride: u面步长
     *
     * rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
     *
     * @return {0} if successful
     */
    public native int SmartPublisherOnYV12Data(long handle, byte[] data, int width, int height, int y_stride,  int v_stride, int u_stride, int rotation_degree);

YUV数据接口

支持标准的I420数据接口对接,不再赘述:

/**
   * 投递层I420图像
   *
   * @param index: 层索引, 必须大于等于0
   *
   * @param left: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param top: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param y_plane: y平面图像数据
   *
   * @param y_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
   *
   * @param y_row_stride: stride information
   *
   * @param u_plane: u平面图像数据
   *
   * @param u_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
   *
   * @param u_row_stride: stride information
   *                    *
   * @param v_plane: v平面图像数据
   *
   * @param v_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
   *
   * @param v_row_stride: stride information
   *
   * @param width: width, 必须大于1, 且必须是偶数
   *
   * @param height: height, 必须大于1, 且必须是偶数
   *
   * @param  is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
   *
   * @param  is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
   *
   * @param  scale_width: 缩放宽,必须是偶数, 0或负数不缩放
   *
   * @param  scale_height: 缩放高, 必须是偶数, 0或负数不缩放
   *
   * @param  scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
   *
   * @param  rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
   *
   * @return {0} if successful
   */
  public native int PostLayerImageI420ByteBuffer(long handle, int index, int left, int top,
                           ByteBuffer y_plane, int y_offset, int y_row_stride,
                           ByteBuffer u_plane, int u_offset, int u_row_stride,
                           ByteBuffer v_plane, int v_offset, int v_row_stride,
                           int width, int height, int is_vertical_flip,  int is_horizontal_flip,
                           int scale_width,  int scale_height, int scale_filter_mode,
                           int rotation_degree);

NV21转I420并旋转

这个接口也是主要用于特定的数据类型对接,NV21的数据,直接转I420后,对接即可,接口参数比较简单,不再赘述。

/**
   * NV21转换到I420并旋转
   *
   * @param src: nv21 data
   *
   * @param dst: 输出I420 data
   *
   * @param width: 图像宽
   *
   * @param height: 图像高
   *
   * rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
   *
   * @return {0} if successful
   */
  public native int SmartPublisherNV21ToI420Rotate(long handle, byte[] src, int src_y_stride, int src_uv_stride, byte[] dst,
                           int dst_y_stride, int dst_u_stride, int dst_v_stride,
                           int width, int height,
                           int rotation_degree);

RGBA

RGBA的主要用于屏幕共享场景下。

/**
    * Set live video data(no encoded data).
    *
    * @param data: RGBA data
    * 
    * @param rowStride: stride information
    * 
    * @param width: width
    * 
    * @param height: height
    *
    * @return {0} if successful
    */
    public native int SmartPublisherOnCaptureVideoRGBAData(long handle,  ByteBuffer data, int rowStride, int width, int height);
    /**
     * 投递裁剪过的RGBA数据
     *
     * @param data: RGBA data
     *
     * @param rowStride: stride information
     *
     * @param width: width
     *
     * @param height: height
     *
     * @param clipedLeft: 左;  clipedTop: 上; clipedwidth: 裁剪后的宽; clipedHeight: 裁剪后的高; 确保传下去裁剪后的宽、高均为偶数
     *
     * @return {0} if successful
     */
    public native int SmartPublisherOnCaptureVideoClipedRGBAData(long handle,  ByteBuffer data, int rowStride, int width, int height, int clipedLeft, int clipedTop, int clipedWidth, int clipedHeight);
    /**
     * Set live video data(no encoded data).
     *
     * @param data: ABGR flip vertical(垂直翻转) data
     *
     * @param rowStride: stride information
     *
     * @param width: width
     *
     * @param height: height
     *
     * @return {0} if successful
     */
    public native int SmartPublisherOnCaptureVideoABGRFlipVerticalData(long handle,  ByteBuffer data, int rowStride, int width, int height);

RGB565

RGB565数据类型也主要用于屏幕采集这块。

/**
     * Set live video data(no encoded data).
     *
     * @param data: RGB565 data
     *
     * @param row_stride: stride information
     *
     * @param width: width
     *
     * @param height: height
     *
     * @return {0} if successful
     */
    public native int SmartPublisherOnCaptureVideoRGB565Data(long handle,ByteBuffer data, int row_stride, int width, int height);

NV12、NV21

/**
   * 投递层NV21图像
   *
   * @param index: 层索引, 必须大于等于0
   *
   * @param left: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param top: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param y_plane: y平面图像数据
   *
   * @param y_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
   *
   * @param y_row_stride: stride information
   *
   * @param uv_plane: uv平面图像数据
   *
   * @param uv_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
   *
   * @param uv_row_stride: stride information
   *
   * @param width: width, 必须大于1, 且必须是偶数
   *
   * @param height: height, 必须大于1, 且必须是偶数
   *
   * @param  is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
   *
   * @param  is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
   *
   * @param  scale_width: 缩放宽,必须是偶数, 0或负数不缩放
   *
   * @param  scale_height: 缩放高, 必须是偶数, 0或负数不缩放
   *
   * @param  scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
   *
   * @param  rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
   *
   * @return {0} if successful
   */
  public native int PostLayerImageNV21ByteBuffer(long handle, int index, int left, int top,
                             ByteBuffer y_plane, int y_offset, int y_row_stride,
                               ByteBuffer uv_plane, int uv_offset, int uv_row_stride,
                               int width, int height, int is_vertical_flip,  int is_horizontal_flip,
                             int scale_width,  int scale_height, int scale_filter_mode,
                             int rotation_degree);
  /**
   * 投递层NV21图像, 详细说明请参考PostLayerImageNV21ByteBuffer
   *
   * @return {0} if successful
   */
  public native int PostLayerImageNV21ByteArray(long handle, int index, int left, int top,
                           byte[] y_plane, int y_offset, int y_row_stride,
                           byte[] uv_plane, int uv_offset, int uv_row_stride,
                           int width, int height, int is_vertical_flip,  int is_horizontal_flip,
                           int scale_width,  int scale_height, int scale_filter_mode,
                           int rotation_degree);
  /**
   * 投递层NV12图像, 详细说明请参考PostLayerImageNV21ByteBuffer
   *
   * @return {0} if successful
   */
  public native int PostLayerImageNV12ByteBuffer(long handle, int index, int left, int top,
                           ByteBuffer y_plane, int y_offset, int y_row_stride,
                           ByteBuffer uv_plane, int uv_offset, int uv_row_stride,
                           int width, int height, int is_vertical_flip,  int is_horizontal_flip,
                           int scale_width,  int scale_height, int scale_filter_mode,
                           int rotation_degree);
  /**
   * 投递层NV12图像, 详细说明请参考PostLayerImageNV21ByteBuffer
   *
   * @return {0} if successful
   */
  public native int PostLayerImageNV12ByteArray(long handle, int index, int left, int top,
                          byte[] y_plane, int y_offset, int y_row_stride,
                          byte[] uv_plane, int uv_offset, int uv_row_stride,
                          int width, int height, int is_vertical_flip,  int is_horizontal_flip,
                          int scale_width,  int scale_height, int scale_filter_mode,
                          int rotation_degree);

RGBA8888、RGBX8888

/**
   * 投递层RGBA8888图像,如果不需要Aplpha通道的话, 请使用RGBX8888接口, 效率高
   *
   * @param index: 层索引, 必须大于等于0, 注意:如果index是0的话,将忽略Alpha通道
   *
   * @param left: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param top: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param rgba_plane: rgba 图像数据
   *
   * @param offset: 图像偏移, 这个主要目的是用来做clip的, 一般传0
   *
   * @param row_stride: stride information
   *
   * @param width: width, 必须大于1, 如果是奇数, 将减1
   *
   * @param height: height, 必须大于1, 如果是奇数, 将减1
   *
   * @param  is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
   *
   * @param  is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
   *
   * @param  scale_width: 缩放宽,必须是偶数, 0或负数不缩放
   *
   * @param  scale_height: 缩放高, 必须是偶数, 0或负数不缩放
   *
   * @param  scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
   *
   * @param  rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
   *
   * @return {0} if successful
   */
  public native int PostLayerImageRGBA8888ByteBuffer(long handle, int index, int left, int top,
                       ByteBuffer rgba_plane, int offset, int row_stride, int width, int height,
                       int is_vertical_flip,  int is_horizontal_flip,
                       int scale_width,  int scale_height, int scale_filter_mode,
                       int rotation_degree);
  /**
   * 投递层RGBA8888图像, 详细说明请参考PostLayerImageRGBA8888ByteBuffer
   *
   * @return {0} if successful
   */
  public native int PostLayerImageRGBA8888ByteArray(long handle, int index, int left, int top,
                            byte[] rgba_plane, int offset, int row_stride, int width, int height,
                            int is_vertical_flip,  int is_horizontal_flip,
                            int scale_width,  int scale_height, int scale_filter_mode,
                            int rotation_degree);
  /**
   * 投递层RGBA8888图像, 详细说明请参考PostLayerImageRGBA8888ByteBuffer
   *
   * @return {0} if successful
   */
  public native int PostLayerImageRGBA8888Native(long handle, int index, int left, int top,
                           long rgba_plane, int offset, int row_stride, int width, int height,
                           int is_vertical_flip,  int is_horizontal_flip,
                           int scale_width,  int scale_height, int scale_filter_mode,
                           int rotation_degree);
  /**
   * 投递层RGBX8888图像
   *
   * @param index: 层索引, 必须大于等于0
   *
   * @param left: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param top: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param rgbx_plane: rgbx 图像数据
   *
   * @param offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
   *
   * @param row_stride: stride information
   *
   * @param width: width, 必须大于1, 如果是奇数, 将减1
   *
   * @param height: height, 必须大于1, 如果是奇数, 将减1
   *
   * @param  is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
   *
   * @param  is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
   *
   * @param  scale_width: 缩放宽,必须是偶数, 0或负数不缩放
   *
   * @param  scale_height: 缩放高, 必须是偶数, 0或负数不缩放
   *
   * @param  scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
   *
   * @param  rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
   *
   * @return {0} if successful
   */
  public native int PostLayerImageRGBX8888ByteBuffer(long handle, int index, int left, int top,
                             ByteBuffer rgbx_plane, int offset, int row_stride, int width, int height,
                             int is_vertical_flip,  int is_horizontal_flip,
                             int scale_width,  int scale_height, int scale_filter_mode,
                             int rotation_degree);
  /**
   * 投递层RGBX8888图像, 详细说明请参考PostLayerImageRGBX8888ByteBuffer
   *
   * @return {0} if successful
   */
  public native int PostLayerImageRGBX8888ByteArray(long handle, int index, int left, int top,
                            byte[] rgbx_plane, int offset, int row_stride, int width, int height,
                            int is_vertical_flip,  int is_horizontal_flip,
                            int scale_width,  int scale_height, int scale_filter_mode,
                            int rotation_degree);
  /**
   * 投递层RGBX8888图像, 详细说明请参考PostLayerImageRGBX8888ByteBuffer
   *
   * @return {0} if successful
   */
  public native int PostLayerImageRGBX8888Native(long handle, int index, int left, int top,
                           long rgbx_plane, int offset, int row_stride, int width, int height,
                           int is_vertical_flip,  int is_horizontal_flip,
                           int scale_width,  int scale_height, int scale_filter_mode,
                           int rotation_degree);
  /**
   * 投递层RGB888图像
   *
   * @param index: 层索引, 必须大于等于0
   *
   * @param left: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param top: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param rgb_plane: rgb888 图像数据
   *
   * @param offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
   *
   * @param row_stride: stride information
   *
   * @param width: width, 必须大于1, 如果是奇数, 将减1
   *
   * @param height: height, 必须大于1, 如果是奇数, 将减1
   *
   * @param  is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
   *
   * @param  is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
   *
   * @param  scale_width: 缩放宽,必须是偶数, 0或负数不缩放
   *
   * @param  scale_height: 缩放高, 必须是偶数, 0或负数不缩放
   *
   * @param  scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
   *
   * @param  rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
   *
   * @return {0} if successful
   */
  public native int PostLayerImageRGB888Native(long handle, int index, int left, int top,
                             long rgb_plane, int offset, int row_stride, int width, int height,
                             int is_vertical_flip,  int is_horizontal_flip,
                             int scale_width,  int scale_height, int scale_filter_mode,
                             int rotation_degree);


相关文章
|
存储 计算机视觉
10位和16位YUV视频格式
10位和16位YUV视频格式
689 0
|
测试技术 C# 容器
深入理解WPF中的依赖注入和控制反转
在WPF开发中,依赖注入(Dependency Injection)和控制反转(Inversion of Control)是程序解耦的关键,在当今软件工程中占有举足轻重的地位,两者之间有着密不可分的联系。今天就以一个简单的小例子,简述如何在WPF中实现依赖注入和控制反转,仅供学习分享使用,如有不足之处,还请指正。
528 0
|
5月前
|
机器学习/深度学习 自然语言处理 算法
分词器详解
分词器将文本转为模型可处理的数字序列,主流算法有BPE、WordPiece和SentencePiece。BPE高效但中文支持弱;WordPiece用于BERT,适合英文;SentencePiece语言无关,支持中日文。实战中常用SentencePiece处理中文,Hugging Face工具处理英文。面试需掌握算法差异、中文分词策略、词汇表设计及OOV问题解决。
|
10月前
|
缓存 前端开发 API
API赋能开发:效率、性能与协作的三重跃升
本文深入解析了现代API开发的核心实践,涵盖接口设计、性能优化与前后端分离协作新模式,助力开发者提升效率,实现团队协同开发。
|
人工智能 算法 自动驾驶
新视角设计下一代时序基础模型,Salesforce推出Moirai-MoE
**Moirai-MoE:时间序列预测的新突破** Salesforce Research团队提出了Moirai-MoE模型,通过稀疏混合专家(MoE)技术,解决了传统时间序列预测方法中存在的频率不可靠和非平稳性问题。该模型在39个数据集上的实验结果表明,其性能优于现有基础模型,具有更高的创新性和泛化能力。论文地址:https://arxiv.org/abs/2410.10469
565 4
三大抽样分布——卡方分布、t分布、F分布
三大抽样分布——卡方分布、t分布、F分布
|
运维 监控 Java
探索Elasticsearch在Java环境下的全文检索应用实践
【4月更文挑战第17天】本文介绍了在Java环境下使用Elasticsearch实现全文检索的步骤。首先,简述了Elasticsearch的功能和安装配置。接着,通过Maven添加`elasticsearch-rest-high-level-client`依赖,创建`RestHighLevelClient`实例连接Elasticsearch。内容包括:创建/删除索引,插入/查询文档。还探讨了高级全文检索功能、性能优化和故障排查技巧。通过Elasticsearch,开发者能高效处理非结构化数据,提升应用程序价值。
397 6
|
SQL 缓存 监控
技术方案到底怎么写?7步完美搞定!
总结了作者多年编写技术方案的经验,介绍了如何通过七个步骤来编写技术方案,包括系统用例、功能链路、核心业务流程、数据库设计、接口设计、非功能设计和系统风险点评估,帮助开发人员更高效地进行系统设计和需求分析。
技术方案到底怎么写?7步完美搞定!
|
设计模式 缓存 算法
谈谈我工作中的23个设计模式
从基础的角度看,设计模式是研究类本身或者类与类之间的协作模式,是进行抽象归纳的一个很好的速成思路。后面阅读设计模式后,为了加深理解,对相关图片进行了描绘和微调。 从技术的角度已经有很多好的总结,本文会换一种角度思考,既然设计模式研究的是类与类的关系,我们作为工作的个体,一些工作中的策略是不是也可以进行类比,可以更好地去思考这些模式?答案是肯定的。
27011 31
谈谈我工作中的23个设计模式
|
存储 人工智能 搜索推荐
开发了一款工具,1 分钟爬楼看完群聊全部精华
开发了一款工具,1 分钟爬楼看完群聊全部精华
1172 0