① 怎樣用c語言c++編碼打開讀取bmp。兩者的的區別。可否用java編寫bmp。為什麼
1C++讀取bmp文件實例
2java讀取bmp文件
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
typedef unsigned char BYTE;//字元型
typedef unsigned short WORD;//短整型
typedef unsigned long DWORD;//長整形
typedef long LONG;
//點陣圖文件頭信息結構定義
//其中不包含文件類型信息(由於結構體的內存結構決定,要是加了的話將不能正確讀取文件信息)
typedef struct tagBITMAPFILEHEADER {
//WORD bfType;
DWORD bfSize; //文件大小
WORD bfReserved1; //保留字,不考慮
WORD bfReserved2; //保留字,同上
DWORD bfOffBits; //實際點陣圖數據的偏移位元組數,即前三個部分長度之和
} BITMAPFILEHEADER;
//信息頭BITMAPINFOHEADER,也是一個結構,其定義如下:
typedef struct tagBITMAPINFOHEADER{
//public:
DWORD biSize; //指定此結構體的長度,為40
LONG biWidth; //點陣圖寬
LONG biHeight; //點陣圖高
WORD biPlanes; //平面數,為1
WORD biBitCount; //採用顏色位數,可以是1,2,4,8,16,24,新的可以是32
DWORD biCompression; //壓縮方式,可以是0,1,2,其中0表示不壓縮
DWORD biSizeImage; //實際點陣圖數據佔用的位元組數
LONG biXPelsPerMeter; //X方向解析度
LONG biYPelsPerMeter; //Y方向解析度
DWORD biClrUsed; //使用的顏色數,如果為0,則表示默認值(2^顏色位數)
DWORD biClrImportant; //重要顏色數,如果為0,則表示所有顏色都是重要的
} BITMAPINFOHEADER;
//調色板Palette,當然,這里是對那些需要調色板的點陣圖文件而言的。24位和32位是不需要調色板的。
//(似乎是調色板結構體個數等於使用的顏色數。)
typedef struct tagRGBQUAD {
//public:
BYTE rgbBlue; //該顏色的藍色分量
BYTE rgbGreen; //該顏色的綠色分量
BYTE rgbRed; //該顏色的紅色分量
BYTE rgbReserved; //保留值
} RGBQUAD;
void showRgbQuan(tagRGBQUAD* pRGB)
{
printf("(%-3d,%-3d,%-3d) ",pRGB->rgbRed,pRGB->rgbGreen,pRGB->rgbBlue);
}
int main(){
char ch,pd;
int b,c,m,d,w,e,f;
int x,y;
unsigned char *q;
int i,j;
unsigned char a[2];
char strFile[50];
BITMAPFILEHEADER bitHead;
BITMAPINFOHEADER bitInfoHead;
tagRGBQUAD *pRgb ;
FILE *fp;
FILE *p;
q=(unsigned char*)malloc(1);
printf("mkx**用C語言編程來讀取BMP文件某一像素點的數據** 請輸入一個bmp文件: ");
scanf("%s",strFile);
fp=fopen(strFile,"rb");
if(fp!=NULL)
{
printf("file open success! ");
WORD fileType;
fread(&fileType,1,sizeof(WORD),fp);
if(fileType != 0x4d42)
{
printf("file is not .bmp file!");
system("pause");
return 0;
}
}
else
{
printf("file open fail! ");
system("pause");
return 0;
}
//讀文件頭信息,並列印文件頭信息各項的值
fread(&bitHead,1,sizeof(tagBITMAPFILEHEADER),fp);
printf("bmp文件頭信息 文件大小:%d 保留字:%d 保留字:%d 實際點陣圖數據的偏移位元組數:%d ",
bitHead.bfSize,bitHead.bfReserved1,bitHead.bfReserved2,bitHead.bfOffBits);
//讀文件信息頭,並列印文件信息頭各項的值
fread(&bitInfoHead,1,sizeof(tagBITMAPINFOHEADER),fp);
printf("bmp文件信息頭 結構體的長度:%d 點陣圖寬:%d 點陣圖高:%d biPlanes平面數:%d biBitCount採用顏色位數:%d 壓縮方式:%d biSizeImage實際點陣圖數據佔用的位元組數:%d X方向解析度:%d Y方向解析度:%d 使用的顏色數:%d 重要顏色數:%d ",
bitInfoHead.biSize,bitInfoHead.biWidth,bitInfoHead.biHeight,bitInfoHead.biPlanes,bitInfoHead.biBitCount,bitInfoHead.biCompression,bitInfoHead.biSizeImage,bitInfoHead.biXPelsPerMeter,bitInfoHead.biYPelsPerMeter,bitInfoHead.biClrUsed,bitInfoHead.biClrImportant);
if(bitInfoHead.biBitCount < 24){
printf("該文件有調色板,即該點陣圖為非真彩色 ");
m=1;
if(bitInfoHead.biBitCount =8){
long nPlantNum = long(pow(2,double(bitInfoHead.biBitCount))); // Mix color Plant Number;
pRgb=(tagRGBQUAD *)malloc(nPlantNum*sizeof(tagRGBQUAD));
memset(pRgb,0,nPlantNum*sizeof(tagRGBQUAD));
int num = fread(pRgb,4,nPlantNum,fp);
printf("Color Plate Number: %d ",nPlantNum);
printf("顏色板信息: ");
for (int i =0; i<nPlantNum;i++)
{
if (i%5==0)
{
printf(" ");
}
showRgbQuan(&pRgb[i]);
}
printf(" ");
}
}
else{
printf("該點陣圖為24位真彩色 ");
m=3;
}
fclose(fp);
while(ch!='N'){
p=fopen(strFile,"rb");
ch=NULL;
f=bitInfoHead.biHeight;
e=bitInfoHead.biWidth;
b=bitHead.bfOffBits;
printf("**輸入指定像素點的數據**(行:1~%d 列1~%d) ",f,e);
printf("請輸入第i行:");
scanf("%d",&x);
printf("請輸入第j列:");
scanf("%d",&y);
c=b+(x-1)*e*m+m*(y-1);
fseek(p,c,0);
//printf("%d ",m);
if(m<2){
fread(&a[0],1,1,p);
printf("該點像素點的數據(十六進制)為:%x ",a[0]);
printf("用十進製表示:%d ",a[0]);
d=a[0];
printf("它對應的rgb值為:");
showRgbQuan(&pRgb[d]);
printf(" ");
}
else {
for(i=0;i<3;i++){
fread(&a[i],1,1,p);
// printf("%x ",a[i]);
}
printf("十六進製表示: 藍:%x 綠:%x 紅:%x ",a[0],a[1],a[2]);
printf("十進製表示: 藍:%d 綠:%d 紅:%d ",a[0],a[1],a[2]);
}
rewind(p);
//w=ftell(p);
//printf("%d",w);
fclose(p);
printf("**繼續請輸入任意字元,如需退出請輸入N ");
getchar();
scanf("%c",&ch);
}
printf("感謝您使用~ ");
system("pause");
return 0;
}
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.MemoryImageSource;
import java.io.FileInputStream;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
//
//really just a collection of methods to read a BMP file
//
public class BMPLoader
{
// build an int from a byte array - convert little to big endian
public static int constructInt(byte[] in, int offset) {
int ret = ((int) in[offset + 3] & 0xff);
ret = (ret << 8) | ((int) in[offset + 2] & 0xff);
ret = (ret << 8) | ((int) in[offset + 1] & 0xff);
ret = (ret << 8) | ((int) in[offset + 0] & 0xff);
return (ret);
}
// build an int from a byte array - convert little to big endian
// set high order bytes to 0xfff
public static int constructInt3(byte[] in, int offset) {
int ret = 0xff;
ret = (ret << 8) | ((int) in[offset + 2] & 0xff);
ret = (ret << 8) | ((int) in[offset + 1] & 0xff);
ret = (ret << 8) | ((int) in[offset + 0] & 0xff);
return (ret);
}
// build an int from a byte array - convert little to big endian
public static long constructLong(byte[] in, int offset) {
long ret = ((long) in[offset + 7] & 0xff);
ret |= (ret << 8) | ((long) in[offset + 6] & 0xff);
ret |= (ret << 8) | ((long) in[offset + 5] & 0xff);
ret |= (ret << 8) | ((long) in[offset + 4] & 0xff);
ret |= (ret << 8) | ((long) in[offset + 3] & 0xff);
ret |= (ret << 8) | ((long) in[offset + 2] & 0xff);
ret |= (ret << 8) | ((long) in[offset + 1] & 0xff);
ret |= (ret << 8) | ((long) in[offset + 0] & 0xff);
return (ret);
}
// build an double from a byte array - convert little to big endian
public static double constructDouble(byte[] in, int offset) {
long ret = constructLong(in, offset);
return (Double.longBitsToDouble(ret));
}
// build an short from a byte array - convert little to big endian
public static short constructShort(byte[] in, int offset) {
short ret = (short) ((short) in[offset + 1] & 0xff);
ret = (short) ((ret << 8) | (short) ((short) in[offset + 0] & 0xff));
return (ret);
}
// internal class representing a bitmap header structure
// with code to read it from a file
static class BitmapHeader {
public int nsize;
public int nbisize;
public int nwidth;
public int nheight;
public int nplanes;
public int nbitcount;
public int ncompression;
public int nsizeimage;
public int nxpm;
public int nypm;
public int nclrused;
public int nclrimp;
// read in the bitmap header
public void read(FileInputStream fs) throws IOException
{
final int bflen = 14; // 14 byte BITMAPFILEHEADER
byte bf[] = new byte[bflen];
fs.read(bf, 0, bflen);
final int bilen = 40; // 40-byte BITMAPINFOHEADER
byte bi[] = new byte[bilen];
fs.read(bi, 0, bilen);
// Interperet data.
nsize = constructInt(bf, 2);
// System.out.println("File type is :"+(char)bf[0]+(char)bf[1]);
// System.out.println("Size of file is :"+nsize);
nbisize = constructInt(bi, 2);
// System.out.println("Size of bitmapinfoheader is :"+nbisize);
nwidth = constructInt(bi, 4);
// System.out.println("Width is :"+nwidth);
nheight = constructInt(bi, 8);
// System.out.println("Height is :"+nheight);
nplanes = constructShort(bi, 12); //(((int)bi[13]&0xff)<<8) |
// (int)bi[12]&0xff;
// System.out.println("Planes is :"+nplanes);
nbitcount = constructShort(bi, 14); //(((int)bi[15]&0xff)<<8) |
// (int)bi[14]&0xff;
// System.out.println("BitCount is :"+nbitcount);
// Look for non-zero values to indicate compression
ncompression = constructInt(bi, 16);
// System.out.println("Compression is :"+ncompression);
nsizeimage = constructInt(bi, 20);
// System.out.println("SizeImage is :"+nsizeimage);
nxpm = constructInt(bi, 24);
// System.out.println("X-Pixels per meter is :"+nxpm);
nypm = constructInt(bi, 28);
// System.out.println("Y-Pixels per meter is :"+nypm);
nclrused = constructInt(bi, 32);
// System.out.println("Colors used are :"+nclrused);
nclrimp = constructInt(bi, 36);
// System.out.println("Colors important are :"+nclrimp);
}
}
public static Image read(FileInputStream fs)
{
try {
BitmapHeader bh = new BitmapHeader();
bh.read(fs);
if (bh.nbitcount == 24)
return (readMap24(fs, bh));
if (bh.nbitcount == 32)
return (readMap32(fs, bh));
if (bh.nbitcount == 8)
return (readMap8(fs, bh));
fs.close();
} catch (IOException e) {
// System.out.println("Caught exception in loadbitmap!");
}
return (null);
}
/**
*
* readMap24 internal routine to read the bytes in a 24 bit bitmap
*
*
*
* Arguments:
*
* fs - file stream
*
* bh - header struct
*
* Returns:
*
* Image Object, be sure to check for (Image)null !!!!
*
*
*
*/
protected static Image readMap32(FileInputStream fs, BitmapHeader bh)
throws IOException
{
Image image;
// No Palatte data for 24-bit format but scan lines are
// padded out to even 4-byte boundaries.
int xwidth = bh.nsizeimage / bh.nheight;
int ndata[] = new int[bh.nheight * bh.nwidth];
byte brgb[] = new byte[bh.nwidth * 4 * bh.nheight];
fs.read(brgb, 0, bh.nwidth * 4 * bh.nheight);
int nindex = 0;
for (int j = 0; j < bh.nheight; j++)
{
for (int i = 0; i < bh.nwidth; i++)
{
ndata[bh.nwidth * (bh.nheight - j - 1) + i] = constructInt3(
brgb, nindex);
nindex += 4;
}
}
image = Toolkit.getDefaultToolkit().createImage
(new MemoryImageSource(bh.nwidth, bh.nheight,
ndata, 0, bh.nwidth));
fs.close();
return (image);
}
/**
*
* readMap24 internal routine to read the bytes in a 24 bit bitmap
*
*
*
* Arguments:
*
* fs - file stream
*
* bh - header struct
*
* Returns:
*
* Image Object, be sure to check for (Image)null !!!!
*
*
*
*/
protected static Image readMap24(FileInputStream fs, BitmapHeader bh)
throws IOException
{
Image image;
// No Palatte data for 24-bit format but scan lines are
// padded out to even 4-byte boundaries.
int npad = (bh.nsizeimage / bh.nheight) - bh.nwidth * 3;
int ndata[] = new int[bh.nheight * bh.nwidth];
byte brgb[] = new byte[(bh.nwidth + npad) * 3 * bh.nheight];
fs.read(brgb, 0, (bh.nwidth + npad) * 3 * bh.nheight);
int nindex = 0;
for (int j = 0; j < bh.nheight; j++)
{
for (int i = 0; i < bh.nwidth; i++)
{
ndata[bh.nwidth * (bh.nheight - j - 1) + i] = constructInt3(
brgb, nindex);
nindex += 3;
}
nindex += npad;
}
image = Toolkit.getDefaultToolkit().createImage
(new MemoryImageSource(bh.nwidth, bh.nheight,
ndata, 0, bh.nwidth));
fs.close();
return (image);
}
/**
*
* readMap8 internal routine to read the bytes in a 8 bit bitmap
*
*
*
* Arguments:
*
* fs - file stream
*
* bh - header struct
*
* Returns:
*
* Image Object, be sure to check for (Image)null !!!!
*
*
*
*/
protected static Image readMap8(FileInputStream fs, BitmapHeader bh)
throws IOException
{
Image image;
// Have to determine the number of colors, the clrsused
// parameter is dominant if it is greater than zero. If
// zero, calculate colors based on bitsperpixel.
int nNumColors = 0;
if (bh.nclrused > 0)
{
nNumColors = bh.nclrused;
}
else
{
nNumColors = (1 & 0xff) << bh.nbitcount;
}
// System.out.println("The number of Colors is"+nNumColors);
// Some bitmaps do not have the sizeimage field calculated
// Ferret out these cases and fix 'em.
if (bh.nsizeimage == 0)
{
bh.nsizeimage = ((((bh.nwidth * bh.nbitcount) + 31) & ~31) >> 3);
bh.nsizeimage *= bh.nheight;
// System.out.println("nsizeimage (backup) is"+nsizeimage);
}
// Read the palatte colors.
int npalette[] = new int[nNumColors];
byte bpalette[] = new byte[nNumColors * 4];
fs.read(bpalette, 0, nNumColors * 4);
int nindex8 = 0;
for (int n = 0; n < nNumColors; n++)
{
npalette[n] = constructInt3(bpalette, nindex8);
nindex8 += 4;
}
// Read the image data (actually indices into the palette)
// Scan lines are still padded out to even 4-byte
// boundaries.
int npad8 = (bh.nsizeimage / bh.nheight) - bh.nwidth;
// System.out.println("nPad is:"+npad8);
int ndata8[] = new int[bh.nwidth * bh.nheight];
byte bdata[] = new byte[(bh.nwidth + npad8) * bh.nheight];
fs.read(bdata, 0, (bh.nwidth + npad8) * bh.nheight);
nindex8 = 0;
for (int j8 = 0; j8 < bh.nheight; j8++)
{
for (int i8 = 0; i8 < bh.nwidth; i8++)
{
ndata8[bh.nwidth * (bh.nheight - j8 - 1) + i8] =
npalette[((int) bdata[nindex8] & 0xff)];
nindex8++;
}
nindex8 += npad8;
}
image = Toolkit.getDefaultToolkit().createImage
(new MemoryImageSource(bh.nwidth, bh.nheight,
ndata8, 0, bh.nwidth));
return (image);
}
/**
*
* load method - see read for details
*
*
*
* Arguments:
*
* sdir and sfile are the result of the FileDialog()
*
* getDirectory() and getFile() methods.
*
*
*
* Returns:
*
* Image Object, be sure to check for (Image)null !!!!
*
*
*
*/
public static Image load(String sdir, String sfile) {
return (load(sdir + sfile));
}
/**
*
* load method - see read for details
*
*
*
* Arguments:
*
* sdir - full path name
*
*
*
* Returns:
*
* Image Object, be sure to check for (Image)null !!!!
*
*
*
*/
public static Image load(String sdir)
{
try
{
FileInputStream fs = new FileInputStream(sdir);
return (read(fs));
}
catch (IOException ex) {
return (null);
}
}
public static void main(String[] args) throws IOException
{
if (args.length == 0) {
System.out.println("Usage >java BMPLoader ImageFile.bmp");
System.exit(0);
}
FileInputStream in = new FileInputStream(args[0]);
Image TheImage = read(in);
JFrame TheFrame = new JFrame(args[0]);
JLabel TheLabel = new JLabel(new ImageIcon(TheImage));
TheFrame.getContentPane().add(new JScrollPane(TheLabel));
TheFrame.setSize(300, 300);
TheFrame.setVisible(true);
}
//end class BMPLoader
}
② 動態規劃演算法如何實現 .bmp灰度圖像壓縮的壓縮與解壓縮啊
誒,轉回來了。但是還差一點。。到底是哪呢。。
③ BMP圖片容量壓縮問題
操作步驟:
第一步、雙擊打開圖片壓縮器,點擊「添加文件」,將需要壓縮的BMP圖片添加進來。
④ 求一個c++的用lzw(字典)演算法來壓縮bmp圖片的代碼
參見gif壓縮演算法源代碼。
1.LZW的全稱是什麼?
Lempel-Ziv-Welch (LZW).
2. LZW的簡介和壓縮原理是什麼?
LZW壓縮演算法是一種新穎的壓縮方法,由Lemple-Ziv-Welch 三人共同創造,用他們的名字命名。它採用了一種先進的串表壓縮,將每個第一次出現的串放在一個串表中,用一個數字來表示串,壓縮文件只存貯數字,則不存貯串,從而使圖象文件的壓縮效率得到較大的提高。奇妙的是,不管是在壓縮還是在解壓縮的過程中都能正確的建立這個串表,壓縮或解壓縮完成後,這個串表又被丟棄。
LZW演算法中,首先建立一個字元串表,把每一個第一次出現的字元串放入串表中,並用一個數字來表示,這個數字與此字元串在串表中的位置有關,並將這個數字存入壓縮文件中,如果這個字元串再次出現時,即可用表示它的數字來代替,並將這個數字存入文件中。壓縮完成後將串表丟棄。如"print" 字元串,如果在壓縮時用266表示,只要再次出現,均用266表示,並將"print"字元串存入串表中,在圖象解碼時遇到數字266,即可從串表中查出266所代表的字元串"print",在解壓縮時,串表可以根據壓縮數據重新生成。
3.在詳細介紹演算法之前,先列出一些與該演算法相關的概念和詞彙
1)'Character': 字元,一種基礎數據元素,在普通文本文件中,它佔用1個單獨的byte,而在圖像中,它卻是 一種代表給定像素顏色的索引值。
2)'CharStream':數據文件中的字元流。
3)'Prefix':前綴。如這個單詞的含義一樣,代表著在一個字元最直接的前一個字元。一個前綴字元長度可以為0,一個prefix和一個character可以組成一個字元串(string),
4)'Suffix': 後綴,是一個字元,一個字元串可以由(A,B)來組成,A是前綴,B是後綴,當A長度為0的時候,代表Root,根
5)'Code:碼,用於代表一個字元串的位置編碼
6)'Entry',一個Code和它所代表的字元串(string)
4.壓縮演算法的簡單示例,不是完全實現LZW演算法,只是從最直觀的角度看lzw演算法的思想
對原始數據ABCCAABCDDAACCDB進行LZW壓縮
原始數據中,只包括4個字元(Character),A,B,C,D,四個字元可以用一個2bit的數表示,0-A,1-B,2-C,3-D,從最直觀的角度看,原始字元串存在重復字元:ABCCAABCDDAACCDB,用4代表AB,5代表CC,上面的字元串可以替代表示為:45A4CDDAA5DB,這樣是不是就比原數據短了一些呢!
5.LZW演算法的適用范圍
為了區別代表串的值(Code)和原來的單個的數據值(String),需要使它們的數值域不重合,上面用0-3來代表A-D,那麼AB就必須用大於3的數值來代替,再舉另外一個例子,原來的數值范圍可以用8bit來表示,那麼就認為原始的數的范圍是0~255,壓縮程序生成的標號的范圍就不能為0~255(如果是0-255,就重復了)。只能從256開始,但是這樣一來就超過了8位的表示範圍了,所以必須要擴展數據的位數,至少擴展一位,但是這樣不是增加了1個字元佔用的空間了么?但是卻可以用一個字元代表幾個字元,比如原來255是8bit,但是現在用256來表示254,255兩個數,還是劃得來的。從這個原理可以看出LZW演算法的適用范圍是原始數據串最好是有大量的子串多次重復出現,重復的越多,壓縮效果越好。反之則越差,可能真的不減反增了。
6.LZW演算法中特殊標記
隨著新的串(string)不斷被發現,標號也會不斷地增長,如果原數據過大,生成的標號集(string table)會越來越大,這時候操作這個集合就會產生效率問題。如何避免這個問題呢?Gif在採用lzw演算法的做法是當標號集足夠大的時候,就不能增大了,乾脆從頭開始再來,在這個位置要插入一個標號,就是清除標志CLEAR,表示從這里我重新開始構造字典,以前的所有標記作廢,開始使用新的標記。
這時候又有一個問題出現,足夠大是多大?這個標號集的大小為比較合適呢?理論上是標號集大小越大,則壓縮比率就越高,但開銷也越高。 一般根據處理速度和內存空間連個因素來選定。GIF規范規定的是12位,超過12位的表達范圍就推倒重來,並且GIF為了提高壓縮率,採用的是變長的字長。比如說原始數據是8位,那麼一開始,先加上一位再說,開始的字長就成了9位,然後開始加標號,當標號加到512時,也就是超過9為所能表達的最大數據時,也就意味著後面的標號要用10位字長才能表示了,那麼從這里開始,後面的字長就是10位了。依此類推,到了2^12也就是4096時,在這里插一個清除標志,從後面開始,從9位再來。
GIF規定的清除標志CLEAR的數值是原始數據字長表示的最大值加1,如果原始數據字長是8,那麼清除標志就是256,如果原始數據字長為4那麼就是16。另外GIF還規定了一個結束標志END,它的值是清除標志CLEAR再加1。由於GIF規定的位數有1位(單色圖),4位(16色)和8位(256色),而1位的情況下如果只擴展1位,只能表示4種狀態,那麼加上一個清除標志和結束標志就用完了,所以1位的情況下就必須擴充到3位。其它兩種情況初始的字長就為5位和9位。此處參照了http://blog.csdn.net/whycadi/
7.用lzw演算法壓縮原始數據的示例分析
輸入流,也就是原始的數據為:255,24,54,255,24,255,255,24,5,123,45,255,24,5,24,54..................
這個正好可以看到是gif文件中像素數組的一部分,如何對它進行壓縮
因為原始數據可以用8bit來表示,故清除標志Clear=255+1 =256,結束標志為End=256+1=257,目前標號集為
0 1 2 3 .................................................................................255 CLEAR END
第一步,讀取第一個字元為255,在標記表裡面查找,255已經存在,我們已經認識255了,不做處理
第二步,取第二個字元,此時前綴為A,形成當前的Entry為(255,24),在標記集合不存在,我們並不認識255,24好,這次你小子來了,我就記住你,把它在標記集合中標記為258,然後輸出前綴A,保留後綴24,並作為下一次的前綴(後綴變前綴)
第三步,取第三個字元為54,當前Entry(24,54),不認識,記錄(24,54)為標號259,並輸出24,後綴變前綴
第四部:取第四個字元255,Entry=(54,255),不認識,記錄(54,255)為標號260,輸出54,後綴變前綴
第五步 取第5個字元24,entry=(255,24),啊,認識你,這不是老258么,於是把字元串規約為258,並作為前綴
第六步 取第六個字元255,entry=(258,255),不認識,記錄(258,255)為261,輸出258,後綴變前綴
.......
一直處理到最後一個字元,
用一個表記錄處理過程
CLEAR=256,END=257
第幾步 前綴 後綴 Entry 認識(Y/N) 輸出 標號
1 255 (,255)
2 255 24 (255,24) N 255 258
3 24 54 (24,54) N 24 259
4 54 255 (54,255) N 54 260
5 255 24 (255,24) Y
6 258 255 (258,255) N 258 261
7 255 255 (255,255) N 255 262
.....
上面這個示例有些不能完整體現,另外一個例子是
原輸入數據為:A B A B A B A B B B A B A B A A C D A C D A D C A B A A A B A B .....
採用LZW演算法對其進行壓縮,壓縮過程用一個表來表述為:
注意原數據中只包含4個character,A,B,C,D
用兩bit即可表述,根據lzw演算法,首先擴展一位變為3為,Clear=2的2次方+1=4; End=4+1=5;
初始標號集因該為
0 1 2 3 4 5
A B C D Clear End
而壓縮過程為:
第幾步 前綴 後綴 Entry 認識(Y/N) 輸出 標號
1 A (,A)
2 A B (A,B) N A 6
3 B A (B,A) N B 7
4 A B (A,B) Y
5 6 A (6,A) N 6 8
6 A B (A,B) Y
7 6 A (6,A) Y
8 8 B (8,B) N 8 9
9 B B (B,B) N B 10
10 B B (B,B) Y
11 10 A (10,A) N 10 11
12 A B (A,B) Y
.....
當進行到第12步的時候,標號集應該為
0 1 2 3 4 5 6 7 8 9 10 11
A B C D Clear End AB BA 6A 8B BB 10A
8.LZW演算法的偽代碼實現
1STRING = get input character
2WHILE there are still input characters DO
3 CHARACTER = get input character
4 IF STRING+CHARACTER is in the string table then
5 STRING = STRING+character
6 ELSE
7 output the code for STRING
8 add STRING+CHARACTER to the string table
9 STRING = CHARACTER
10 END of IF
11END of WHILE
12output the code for STRING
13
⑤ 怎麼壓縮bmp格式的圖片大小
bmp格式不能壓縮的,要減小體積只能被壓縮成jpg或者png格式了。用這個在線圖片壓縮工具試試吧,可以壓縮bmp格式,想把圖片文件的大小減到多少都行,直接設置一下數值就搞定,馬上瞬間就能壓縮完。在線智能壓縮圖片大小,圖片壓縮體積
在線圖片智能壓縮使用步驟:
一、首先點擊加號添加需要壓縮的圖片。目前已知支持對jpg、png等多種常見的圖片格式進行壓縮,如果上傳圖片並壓縮成功,則代表支持該圖片格式。
二、可以自行修改圖片需要被壓縮到的最大寬高尺寸,默認為圖片原始的寬高尺寸,且寬高比例是自動鎖定的。
三、必須設置圖片被壓縮後,期望輸出的圖片文件的最大佔用空間。(必填項)
四、選擇圖片生成的演算法。默認為混合優先演算法,絕大多數情況下使用默認演算法即可。
五、壓縮的設定值不能小於1Kb,但圖片壓縮的最終效果可以小於1Kb。
butterpig