本文目錄:
- 簡介
- 快速通道
- 翻譯--image庫
1. 簡介
Rust這門編程語言魅力非常。奈何在國內(nèi)風(fēng)名不顯荣倾,對(duì)于一些已經(jīng)造好的輪子悯搔,卻也還是晦澀的英文版。本著學(xué)習(xí)的目的舌仍,加深自身的理解妒貌,將逐步將一些使用的Rust庫進(jìn)行自己理解后翻譯至此。(ps:名義上是翻譯铸豁,實(shí)際上是自己閱讀后的理解灌曙,并非逐字翻譯,關(guān)心原文者节芥,請(qǐng)前往英文原文Orz)
2. 快速通道
所有的翻譯文章將集中導(dǎo)航于:Rust常用庫翻譯計(jì)劃
3.翻譯——image庫
庫簡介
image庫是Rust的一個(gè)處理圖片的庫在刺,提供了基礎(chǔ)的圖片處理以及格式轉(zhuǎn)換等等的對(duì)應(yīng)函數(shù)實(shí)現(xiàn)逆害。
該庫提供的函數(shù)的處理對(duì)象全是"GenericImage" trait 的實(shí)例,并且返回一個(gè)ImageBuffer蚣驼。
關(guān)于"GenericImage" trait(待翻譯)
關(guān)于ImageBuffer(待翻譯)
使用方法
在項(xiàng)目的Cargo.toml中加入以下依賴:
[dependencies]
image = "*"
然后在你的代碼中引用該庫:
extern crate image;
支持的格式
目前該庫基本支持市面上大部分的圖片格式
- PNG (encode & decode)
- JPEG (encode & decode)
- GIF (encode & decode)
- BMP (encode & decode)
- ICO (encode & decode)
- TIFF (just decode)
- webp (just decode)
- PPM (encode & decode)
關(guān)于ImageDecoder Trait
所有的deocoder全部實(shí)現(xiàn)于ImageDecoder Trait中的定義魄幕。文檔傳送門
具體定義:
pub trait ImageDecoder: Sized {
fn dimensions(&mut self) -> ImageResult<(u32, u32)>;
fn colortype(&mut self) -> ImageResult<ColorType>;
fn row_len(&mut self) -> ImageResult<usize>;
fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32>;
fn read_image(&mut self) -> ImageResult<DecodingResult>;
fn is_animated(&mut self) -> ImageResult<bool> { ... }
fn into_frames(self) -> ImageResult<Frames> { ... }
fn load_rect(
&mut self,
x: u32,
y: u32,
length: u32,
width: u32
) -> ImageResult<Vec<u8>> { ... }
}
可以看出,該trait定義了八個(gè)函數(shù)颖杏,其中六個(gè)是所有該庫中實(shí)現(xiàn)該trait的實(shí)例中都實(shí)現(xiàn)了的函數(shù):
- dimensions:返回泛型T為(u32,u32)的imageResult纯陨,具體實(shí)現(xiàn)時(shí),是返回寬度和高度的元組
- colorType:返回泛型為colorType的imageResult留储,其中colorType為圖片對(duì)應(yīng)的色彩類型翼抠,定義如下:
pub enum ColorType {
Gray(u8),
RGB(u8),
Palette(u8),
GrayA(u8),
RGBA(u8),
}
- row_len 返回T為usize的imageResult,實(shí)現(xiàn)時(shí)為返回decode后每行的字節(jié)數(shù)
- read_scanline:返回T為u32的imageResult获讳,實(shí)現(xiàn)時(shí)為讀取一行圖片數(shù)據(jù)到傳入的buf中阴颖,然后返回index索引
- read_image: 讀取全部圖片數(shù)據(jù),以vector形式返回imageResult
- load_ract: 讀取特定矩形區(qū)域內(nèi)的數(shù)據(jù)丐膝,返回vector數(shù)組
關(guān)于“GenericImage” Trait
"GenericImage" Trait 提供了一系列的處理image的方法量愧,最常見的,當(dāng)我們使用image庫提供的open函數(shù)時(shí),成功會(huì)返回一個(gè)DynamicImage的枚舉帅矗,而枚舉就實(shí)現(xiàn)了"GenericImage" Trait侠畔。先看看"GenericImage" Trait的定義:
pub trait GenericImage: Sized {
type Pixel: Pixel;
fn dimensions(&self) -> (u32, u32);
fn bounds(&self) -> (u32, u32, u32, u32);
fn get_pixel(&self, x: u32, y: u32) -> Self::Pixel;
fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut Self::Pixel;
fn put_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel);
fn blend_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel);
fn width(&self) -> u32 { ... }
fn height(&self) -> u32 { ... }
fn in_bounds(&self, x: u32, y: u32) -> bool { ... }
unsafe fn unsafe_get_pixel(&self, x: u32, y: u32) -> Self::Pixel { ... }
unsafe fn unsafe_put_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel) { ... }
fn pixels(&self) -> Pixels<Self> { ... }
fn pixels_mut(&mut self) -> MutPixels<Self> { ... }
fn copy_from<O>(&mut self, other: &O, x: u32, y: u32) -> bool
where
O: GenericImage<Pixel = Self::Pixel>,
{ ... }
fn sub_image<'a>(
&'a mut self,
x: u32,
y: u32,
width: u32,
height: u32
) -> SubImage<'a, Self>
where
Self: 'static,
Self::Pixel::Subpixel: 'static,
Self::Pixel: 'static,
{ ... }
}
其中六個(gè)函數(shù)是必須實(shí)現(xiàn)的:
- dimensions: 同上文的dimensions
- bounds: 測試后發(fā)現(xiàn)是返回左上坐標(biāo)和右下坐標(biāo)(求指正)
- get_pixel: 返回傳入坐標(biāo)位置的像素信息,定義上是返回一個(gè)"pixel" trait實(shí)例,在實(shí)際運(yùn)行中其實(shí)就是返回結(jié)構(gòu)體RGB,RGBA,Luma,LumaA之一损晤,這幾個(gè)實(shí)例都實(shí)現(xiàn)了"pixel" trait。同時(shí)包含了了data屬性红竭,為一個(gè)vector數(shù)組尤勋,包含十進(jìn)制的色彩信息
- get_pixel_mut:見名知其意,返回的是一個(gè)可寫的"pixel" trait實(shí)例
- put_pixel: 將對(duì)應(yīng)位置的像素替換為傳入的pixel實(shí)例
- blend_pixel: 即將廢棄,就不說明了
關(guān)于圖片內(nèi)容的表示
文檔中表示image庫提供了兩種方式來表示圖片內(nèi)容茵宪。其一就是直接操作struct “imageBuffer”來實(shí)現(xiàn)最冰,其二就是“DynamicImage”
imageBuffer
imageBuffer同樣見名知其意,就是直接操縱buffer中的像素信息稀火,一般用于新建一張已知類型的圖片暖哨。同樣,在其上實(shí)現(xiàn)了“GenericImage” Trait凰狞,可以使用其中的函數(shù)篇裁。
示例(官方示例,小生改了注釋):
extern crate image;
use image::{
GenericImage,
ImageBuffer
};
//利用imageBuffer的new函數(shù)構(gòu)建一個(gè)新的buffer赡若,傳入的參數(shù)是新建圖像的寬高
let img = ImageBuffer::new(512, 512);
//利用imageBuffer的from_fn函數(shù)構(gòu)建一個(gè)新的buffer达布,傳入?yún)?shù)為新建圖像的寬高,然后圖像中的每個(gè)像素都會(huì)被第三個(gè)參數(shù)所處理
let img = ImageBuffer::from_fn(512, 512, |x, y| {
if x % 2 == 0 {
image::Luma([0u8])
} else {
image::Luma([255u8])
}
});
//由于實(shí)例化了“GenericImage” Trait逾冬,所以可以直接使用dimensions
let (width, height) = img.dimensions();
//可以類似于數(shù)組一樣黍聂,傳入xy元組索引獲取對(duì)應(yīng)位置像素
let pixel = img[(100, 100)];
//當(dāng)然躺苦,也可以使用“GenericImage” Trait中的get_pixel函數(shù)來獲取對(duì)應(yīng)位置的像素
let pixel = img.get_pixel(100, 100);
//替換像素也是同樣的
img.put_pixel(100, 100, pixel);
//pixels函數(shù)可以返回所有像素的位置以及像素信息,并且由于pixel實(shí)現(xiàn)了iterator匹厘,所以可以直接使用for循環(huán)進(jìn)行遍歷
for pixel in img.pixels() {
//pixel此時(shí)為(x,y,RGBA{data:[0,0,0,0]}),RGBA可能為其他任何該庫中定義的色彩類型,data值為對(duì)應(yīng)通道的十進(jìn)制值
}
DynamicImage
DynamicImage其實(shí)和imageBuffer差不太多脐区,只是DynamicImage中像素的色彩類型是不定的愈诚,在運(yùn)行時(shí)才確定,所以當(dāng)使用open函數(shù)打開一個(gè)圖片時(shí)哩罪,便是返回的這個(gè)類型的句柄,同樣捕捂,它也是實(shí)現(xiàn)了“GenericImage” Trait(僅在像素類型為RGBA時(shí))瑟枫,當(dāng)然,他也自身實(shí)現(xiàn)了大量的函數(shù)指攒,快速傳送門
示例(這下是小生獻(xiàn)丑寫的了):
extern crate image;
use std::path::Path;
use image::GenericImage;
fn main() {
let img=image::open(&Path::new("1.png")).unwrap();
println!("dimonsions:{:?}",img.dimensions());
println!("width:{:?}",img.width());
println!("bounds:{:?}",img.bounds());
println!("(10,10)'s pixel:{:?}",img.get_pixel(10,10))
}
關(guān)于圖像處理的一些函數(shù)
ps:這些函數(shù)位于“imageops” module中慷妙,操作對(duì)象皆為“GenericImage” Trait 的實(shí)例,快速傳送門