ROS發送來的地圖都是PMG的格式的圖片,wpf並不支持,找了好久找到了轉換的方法。ui
public class PgmImage { public int width; public int height; public int maxVal; public byte[][] pixels; public static int SplitUnit = 3000; //按2000* 2000pix分割圖片 不要修改此值 public PgmImage(int width, int height, int maxVal, byte[][] pixels) { this.width = width; this.height = height; this.maxVal = maxVal; this.pixels = pixels; } public static PgmImage LoadImage(string file) { FileStream ifs = new FileStream(file, FileMode.Open); BinaryReader br = new BinaryReader(ifs); string magic = NextNonCommentLine(br); if (magic != "P5") throw new Exception("Unknown magic number: " + magic); string widthHeight = NextNonCommentLine(br); string[] tokens = widthHeight.Split(' '); int width = int.Parse(tokens[0]); int height = int.Parse(tokens[1]); string sMaxVal = NextNonCommentLine(br); int maxVal = int.Parse(sMaxVal); byte[][] pixels = new byte[height][]; for (int i = 0; i < height; ++i) pixels[i] = new byte[width]; for (int i = 0; i < height; ++i) for (int j = 0; j < width; ++j) pixels[i][j] = br.ReadByte(); br.Close(); ifs.Close(); PgmImage result = new PgmImage(width, height, maxVal, pixels); return result; } private static string NextAnyLine(BinaryReader br) { string s = ""; byte b = 0; // dummy while (b != 10) // newline { b = br.ReadByte(); char c = (char)b; s += c; } return s.Trim(); } private static string NextNonCommentLine(BinaryReader br) { string s = NextAnyLine(br); while (s.StartsWith("#") || s == "") s = NextAnyLine(br); return s; } public static List<string> MakeBitmap(string dir, int mag, string file, out int width, out int height, out string mainImagePath, BackgroundWorker worker) { PgmImage pgmImage = LoadImage(file); List<string> listPics = new List<string>(); width = pgmImage.width * mag; height = pgmImage.height * mag; long total = width * height; long counter = 0; int pro = 0; int splitUnit = PgmImage.SplitUnit / mag; //Bitmap bitmapMain = new Bitmap(width, height); //Graphics grMain = Graphics.FromImage(bitmapMain); for (int i = 0; i < pgmImage.width / splitUnit + 1; i++) { int tempWidth = splitUnit * mag; if (i == pgmImage.width / splitUnit) tempWidth = width % (splitUnit * mag); else tempWidth = splitUnit * mag; for (int j = 0; j < pgmImage.height / splitUnit + 1; j++) { int tempHeight = splitUnit * mag; if (j == pgmImage.height / splitUnit) tempHeight = height % (splitUnit * mag); else tempHeight = splitUnit * mag; Bitmap bitmap = new Bitmap(tempWidth, tempHeight); Graphics gr = Graphics.FromImage(bitmap); for (int m = j * splitUnit; m < Math.Min(pgmImage.height, (j + 1) * splitUnit); ++m) { for (int k = i * splitUnit; k < Math.Min(pgmImage.width, (i + 1) * splitUnit); ++k) { int pixelColor = pgmImage.pixels[m][k]; System.Drawing.Color c = System.Drawing.Color.FromArgb(pixelColor, pixelColor, pixelColor); SolidBrush sb = new SolidBrush(c); gr.FillRectangle(sb, (k- i* splitUnit) * mag, (m - j * splitUnit) * mag, mag, mag); //grMain.FillRectangle(sb, k * mag, m * mag, mag, mag); counter = counter + (mag * mag); int temppro = (int)((counter * 100) / total); if (pro != temppro) { pro = temppro; worker.ReportProgress(pro); } } } FileInfo info = new FileInfo(file); string saveFile = dir + Guid.NewGuid().ToString() + info.Name.Replace("pgm", "bmp"); bitmap.Save(saveFile); listPics.Add(saveFile); bitmap.Dispose(); gr.Dispose(); } } FileInfo infoMain = new FileInfo(file); string saveFileMain = dir + infoMain.Name.Replace("pgm", "bmp"); //bitmapMain.Save(saveFileMain); //bitmapMain.Dispose(); //grMain.Dispose(); mainImagePath = saveFileMain; return listPics; } private static byte[] Bitmap2Byte(Bitmap bitmap) { using (MemoryStream stream = new MemoryStream()) { bitmap.Save(stream, ImageFormat.Jpeg); byte[] data = new byte[stream.Length]; stream.Seek(0, SeekOrigin.Begin); stream.Read(data, 0, Convert.ToInt32(stream.Length)); return data; } } /// <summary> /// 從圖片中截取部分生成新圖 /// </summary> /// <param name= "sFromFilePath "> 原始圖片 </param> /// <param name= "saveFilePath "> 生成新圖 </param> /// <param name= "width "> 截取圖片寬度 </param> /// <param name= "height "> 截取圖片高度 </param> /// <param name= "spaceX "> 截圖圖片X座標 </param> /// <param name= "spaceY "> 截取圖片Y座標 </param> public static List<string> SplitImage(string dir, List<byte[]> datas) { List<string> files = new List<string>(); foreach (byte[] item in datas) { MemoryStream ms1 = new MemoryStream(item); Bitmap bm = (Bitmap)Image.FromStream(ms1); ms1.Close(); string fileName = string.Format("{0}{1}.bmp", dir, Guid.NewGuid().ToString()); bm.Save(fileName); files.Add(fileName); } return files; } }