位图的存储方式

开始之前,先了解下位图的存储方式

位图的像素都分配有特定的位置和颜色值。每个像素的颜色信息由RGB组合或者灰度值表示,根据位深度,可将位图分为1、4、8、16、24及32位图像等。每个像素使用的信息位数越多,可用的颜色就越多,颜色表现就越逼真,相应的数据量越大。位图的深度就是每个像素用多少位表示,详情如下:

8位:  2^8 = 2^2(B) 2^3(G) 2^3(R) = 256  (256色)    可以总共显示256种颜色

16位:2^16 = 2^5(B) 2^6(G) 2^5(R) =  65536    可以总共显示65536种颜色

24位:2^24 = 2^8(B) 2^8(G) 2^8(R) =  16777216    可以总共显示16777216种颜色

32位:Alpha透明度 + 24位

在winform时代,处理位图使用的是System.Drawing命名空间,wpf之后新加了一个命名空间做位图处理:System.Windows.Media.Imaging,该namespace里提供一些类型,这些类型可用于对位图图像进行编码和解码。

显示图像

最简单的位图处理,显示一个图片到控件上,使用Image控件加载图像文件成BitmapImage:

bitmapImage.BeginInit();
bitmapImage.UriSource = new Uri(@"D:\xxx.jpg");
bitmapImage.EndInit();

Image控件的Source属性就是BitmapImage类型

在msdn上对BitmapImage的介绍如下:

提供一个专用的 BitmapSource(继承自System.Windows.Media.Imaging.BitmapSource)

已使用 Extensible Application Markup Language (XAML) 针对加载图像进行了优化。

这里我们暂时先不管BitmapImage,先看看他的父类BitmapSource

System.Windows.Media.Imaging.BitmapSource

表示在一定大小和分辨率下的单个恒定像素集。也就是说BitmapSource代表一个位图图像文件。

BitmapSource是Windows Presentation Foundation (WPF)图像处理管道的基本构建基块, 从概念上讲, 以一定大小和分辨率来表示一组固定的像素。

也就是说,BitmapSource就代表一系列像素组成的位图图像,该类是一系列位图处理类的基类,该类有如下子类:

InteropBitmap

BitmapFrame

BitmapImage

CachedBitmap

ColorConvertedBitmap

CroppedBitmap

FormatConvertedBitmap

RenderTargetBitmap

TransformedBitmap

WriteableBitmap

msdn为我们提供了一个创建BitmapSource的实例

// Define parameters used to create the BitmapSource.
PixelFormat pf = PixelFormats.Bgr32;
int width = 200;
int height = 200;
int rawStride = (width * pf.BitsPerPixel + 7) / 8;
byte[] rawImage = new byte[rawStride * height]; // Initialize the image with data.使用随机数填充像素
Random value = new Random();
value.NextBytes(rawImage); // Create a BitmapSource.
BitmapSource bitmap = BitmapSource.Create(width, height,
96, 96, pf, null,
rawImage, rawStride); // Create an image element;
Image myImage = new Image();
myImage.Width = 200;
// Set image source.
myImage.Source = bitmap;

很明显,在上面的例子中BitmapSource中每一个像素是占32位的(PixelFormats.Bgr32 也就是sRGB)。

再谈BitmapImage

继承自BitmapSource,新加了四个方法分别是:BeginInit()、EndInit()、Clone()、CloneCurrentValue()

该类主要功能是可以从图像文件获得BitmapSource,使用BeginInit和EndInit()

// Create the image element.
Image simpleImage = new Image();
simpleImage.Width = 200;
simpleImage.Margin = new Thickness(5); // Create source.
BitmapImage bi = new BitmapImage();
// BitmapImage.UriSource must be in a BeginInit/EndInit block.
bi.BeginInit();
bi.UriSource = new Uri(@"/sampleImages/cherries_larger.jpg",UriKind.RelativeOrAbsolute);
bi.EndInit();
// Set the image source.
simpleImage.Source = bi;

另外他还有个StreamSource属性可以从流直接获取图像。

RenderTargetBitmap

用于转换System.Windows.Media.visual对象(所有wpf控件的基类)成位图

只有两个方法Clear()和void Render(Visual visual)

Render就是渲染Visual对象(wpf控件都是Visual的子类)成位图,截图软件控件的时候使用该类

BitmapFrame

根据给定的url或者BitmapSoutce或者stream创建新的BitmapFrame

表示一帧图像,在BitmapEncoder和BitmapDecoder中都有List的集合来表示很多帧图像数据。

继承自BitmapSource,只有一个方法Create()该函数返回值也是BitmapFrame

TransformedBitmap

缩放和旋转BitmapSource

BitmapEncoder

抽象类,将 BitmapFrame对象的集合编码为图像流

一个重要的方法Save(Stream st),将位图图像编码为指定的 Stream。处理完图像要保存成文件或者流一定会用到这个类。

派生(分格式编码)

BmpBitmapEncoder

GifBitmapEncoder

JpegBitmapEncoder

PngBitmapEncoder

TiffBitmapEncoder

WmpBitmapEncoder

有一个List Frames的集合,集合的每一个对象是一个BitmapFrame对象,表示一帧图像

图像与字节数组转换的思路

文件字节数组:文件的byte形式。

Pixel字节数组:数组的每个元素代表一个像素,可以存储8位256色的像素。

以上两个字节数组是不一样的。

如果是图像文件,那么使用File.ReadAllBits()方法可以得到该文件的bytes数组。如果是BitmapSource类型或者其子类的结构可以考虑使用MemoryStream,

MemoryStream类有一个ToArray()方法,msdn是这样介绍的:

将流内容写入字节数组,而与 Position 属性无关。

位图图像转换成字节数组就是要用到这个方法,思路就是用MemoryStream做一次中间转换,先把位图写入到MemoryStream中然后调用ToArray()方法。

注意,这里得到的是文件的byte数组,并不是上文介绍BitmapSource中用到的像素数组,要得到BitmapSource的像素数组可以使用BItmapSource.CopyPixels()方法。

位图转成base64的思路

Convert有个方法:Convert.ToBase64String(),核心参数就是byte[] (从文件读取File.ReadAllBytes,或者从流读取MemoryStream.ToArray),所以思路就是将位图转换成byte[]然后使用Convert.ToBase64String()即可。

WPF 位图处理相关类的更多相关文章

  1. WPF图形图像相关类

    BitmapMetadata类: 继承自抽象类ImageMetadata,包含图像的原数据信息,如相机型号.图像修改程序名称.拍照日期.拍照地点等.ImageSoure类包含ImageMetadata ...

  2. WPF自学入门(九)WPF自定义窗口基类

    今天简单记录一个知识点:WPF自定义窗口基类,常用winform的人知道,winform的窗体继承是很好用的,写一个基础窗体,直接在后台代码改写继承窗体名.但如果是WPF要继承窗体,我个人感觉没有理解 ...

  3. Android随笔之——Android时间、日期相关类和方法

    今天要讲的是Android里关于时间.日期相关类和方法.在Android中,跟时间.日期有关的类主要有Time.Calendar.Date三个类.而与日期格式化输出有关的DateFormat和Simp ...

  4. 21 BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类

    21_BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类 BasicTaskScheduler基本任务调度器 BasicTaskScheduler基 ...

  5. 8 延时队列相关类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  6. 4 Handler相关类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. Handler相关类概述 处理程序相关类一共有三个,其没有派生继承关系,但是其有友元关系和使用关系 ...

  7. MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)

    前面讲了模态对话框和非模态对话框,本节来将一种特殊的对话框--属性页对话框. 属性页对话框的分类 属性页对话框想必大家并不陌生,XP系统中桌面右键点属性,弹出的就是属性页对话框,它通过标签切换各个页面 ...

  8. android 6.0 SDK中删除HttpClient的相关类的解决方法

    一.出现的情况 在eclipse或 android studio开发, 设置android SDK的编译版本为23时,且使用了httpClient相关类的库项目:如android-async-http ...

  9. Android 6.0删除Apache HttpClient相关类的解决方法

    相应的官方文档如下: 上面文档的大致意思是,在Android 6.0(API 23)中,Google已经移除了Apache HttpClient相关的类,推荐使用HttpUrlConnection. ...

随机推荐

  1. HDU 4386 Quadrilateral(四边形的海伦公式的应用)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=115760#problem/G 题目大意是给出四条边,问能否组成一个四边形,如果 ...

  2. JavaEE三大框架的整合

    JavaEE三大框架的整合                                                                                       ...

  3. ORM SQLAlchemy 简介

    对象关系映射(Object Relational Mapping,简称ORM使用DB-API访问数据库,需要懂 SQL 语言,能够写 SQL 语句,如果不想懂 SQL,又想使用关系型数据库,可以使用 ...

  4. vim 快捷键 清空文件所有内容

    vim清空文件所有内容 在使用vim编辑器的时候,有时候编辑一个文件,而文件内容比较多,如果需要快速清空整个文件,可以使用一下命令: 在命令模式下,首先执行 gg 这里是跳至文件首行 再执行: dG ...

  5. kotlin之null值安全性

    var a: String =null // 编译错误 var a: String? =null // 编译通过 要允许null值, 需要将变量声明为可为null的字符串类型:String? fun ...

  6. kotlin 泛型中类型投射

    fun main(arg: Array<String>) { var ints:Array<Int> = arrayOf(, , ) val any =Array<Any ...

  7. 虚拟化技术实现 — QEMU-KVM

    目录 文章目录 目录 前文列表 KVM QEMU QEMU-KVM QEMU-KVM 调用 KVM 内核模块启动虚拟机的流程概要 前文列表 <虚拟化技术实现 - 虚拟化技术发展编年史> K ...

  8. CockroachDB学习笔记——[译]Cgo的成本与复杂性

    原文链接:https://www.cockroachlabs.com/blog/the-cost-and-complexity-of-cgo/ 原作者:Tobias Schottdorf 原文日期:D ...

  9. leetcode 四数之和

    这里我们可以考虑将 n 数之和降低为一个数加上 n-1 数之和的问题.依次降低 ,最低是二数之和的问题 ,二数之和问题容易解决.主要在于从 n 到 n-1 的过程需要理解 :下列代码中前几个 if 是 ...

  10. Linux操作系统使用RPMBUILD命令打包RPM的详细步骤

    首先,我们需要了解一些预备知识,在旧版本的CentOS中,rpmbuild工具默认的工作路径是/usr/src/redhat,因为权限原因,一般用户身份不能制作rpm软件包,只能切换到root身份才能 ...