c#中将dicom文件格式转换成可读图片

不多说,直接上代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Drawing;
using System.Text.RegularExpressions;namespace TestForm
{class DicomHandler{string fileName = "";Dictionary<string, string> tags = new Dictionary<string, string>();//dicom文件中的标签 BinaryReader dicomFile;//dicom文件流 //文件元信息 public Bitmap gdiImg;//转换后的gdi图像 UInt32 fileHeadLen;//文件头长度 long fileHeadOffset;//文件数据开始位置 UInt32 pixDatalen;//像素数据长度 long pixDataOffset = 0;//像素数据开始位置 bool isLitteEndian = true;//是否小端模式(小端在前 、大端在前) bool isExplicitVR = true;//有无VR //像素信息 int colors;//颜色数 RGB为3 黑白为1 public int windowWith = 0, windowCenter = 0 / 2;//在未设定时 窗宽窗位为0 int rows, cols;public void readAndShow(TextBox textBox1){if (fileName == string.Empty)return;dicomFile = new BinaryReader(File.OpenRead(fileName));//跳过128字节导言部分 dicomFile.BaseStream.Seek(128, SeekOrigin.Begin);if (new string(dicomFile.ReadChars(4)) != "DICM"){MessageBox.Show("没有dicom标识头,文件格式错误");return;}textBox1.Clear();tagRead();IDictionaryEnumerator enor = tags.GetEnumerator();while (enor.MoveNext()){if (enor.Key.ToString().Length > 9){textBox1.Text += enor.Key.ToString() + "\r\n";textBox1.Text += enor.Value.ToString().Replace('\0', ' ');}elsetextBox1.Text += enor.Key.ToString() + enor.Value.ToString().Replace('\0', ' ') + "\r\n";}dicomFile.Close();}public DicomHandler(string _filename){fileName = _filename;}public void saveAs(string filename){switch (filename.Substring(filename.LastIndexOf('.'))){case ".jpg":gdiImg.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg);break;case ".bmp":gdiImg.Save(filename, System.Drawing.Imaging.ImageFormat.Bmp);break;case ".png":gdiImg.Save(filename, System.Drawing.Imaging.ImageFormat.Png);break;case ".gif":gdiImg.Save(filename, System.Drawing.Imaging.ImageFormat.Gif);break;default:break;}}//获取图像 在图像数据偏移量已经确定的情况下(附带简略调窗代码)  public bool getImg(){if (fileName == string.Empty)return false;int dataLen, validLen, hibit;//数据长度 有效位 //int imgNum;//帧数 rows = int.Parse(tags["0028,0010"].Substring(5));cols = int.Parse(tags["0028,0011"].Substring(5));colors = int.Parse(tags["0028,0002"].Substring(5));dataLen = int.Parse(tags["0028,0100"].Substring(5));//bits allocated validLen = int.Parse(tags["0028,0101"].Substring(5));bool signed = int.Parse(tags["0028,0103"].Substring(5)) == 0 ? false : true;hibit = int.Parse(tags["0028,0102"].Substring(5));float rescaleSlop = 1, rescaleinter = 0;if (tags.ContainsKey("0028,1052") && tags.ContainsKey("0028,1053")){rescaleSlop = float.Parse(tags["0028,1053"].Substring(5));rescaleinter = float.Parse(tags["0028,1052"].Substring(5));}//读取预设窗宽窗位 //预设窗值读取代码...... #region//读取预设窗宽窗位 if (windowWith == 0 && windowCenter == 0){Regex r = new Regex(@"([0-9]+)+");if (tags.ContainsKey("0028,1051")){Match m = r.Match(tags["0028,1051"].Substring(5));if (m.Success)windowWith = int.Parse(m.Value);elsewindowWith = 1 << validLen;}else{windowWith = 1 << validLen;}if (tags.ContainsKey("0028,1050")){Match m = r.Match(tags["0028,1050"].Substring(5));if (m.Success)windowCenter = int.Parse(m.Value);//窗位 elsewindowCenter = windowWith / 2;}else{windowCenter = windowWith / 2;}}#endregiongdiImg = new Bitmap(cols, rows);BinaryReader dicomFile = new BinaryReader(File.OpenRead(fileName));dicomFile.BaseStream.Seek(pixDataOffset, SeekOrigin.Begin);long reads = 0;int max = 0, min = int.MaxValue;for (int i = 0; i < gdiImg.Height; i++){for (int j = 0; j < gdiImg.Width; j++){if (reads >= pixDatalen)break;byte[] pixData;pixData = dicomFile.ReadBytes(dataLen / 8 * colors);reads += pixData.Length;Color c = Color.Empty;if (colors == 1){int grayGDI;double gray;if (validLen <= 8)gray = (double)pixData[0];else{if (isLitteEndian == false)Array.Reverse(pixData, 0, 2);if (signed == false)gray = BitConverter.ToUInt16(pixData, 0);elsegray = BitConverter.ToInt16(pixData, 0);if ((rescaleSlop != 1.0f) || (rescaleinter != 0.0f)){float fValue = (float)gray * rescaleSlop + rescaleinter;gray = (short)fValue;}if (gray > max)max = (int)gray;if (gray < min)min = (int)gray;}//调窗代码,就这么几句而已  //1先确定窗口范围 2映射到8位灰度 int grayStart = (windowCenter - windowWith / 2);int grayEnd = (windowCenter + windowWith / 2);if (gray < grayStart)grayGDI = 0;else if (gray > grayEnd)grayGDI = 255;else{grayGDI = (int)((gray - grayStart) * 255 / windowWith);}if (grayGDI > 255)grayGDI = 255;else if (grayGDI < 0)grayGDI = 0;c = Color.FromArgb(grayGDI, grayGDI, grayGDI);}else if (colors == 3){c = Color.FromArgb(pixData[0], pixData[1], pixData[2]);}gdiImg.SetPixel(j, i, c);}}dicomFile.Close();return true;}void tagRead()//不断读取所有tag 及其值 直到碰到图像数据 (7fe0 0010 ) {bool enDir = false;int leve = 0;StringBuilder folderData = new StringBuilder();//该死的文件夹标签 string folderTag = "";while (dicomFile.BaseStream.Position + 6 < dicomFile.BaseStream.Length){//读取tag string tag = dicomFile.ReadUInt16().ToString("x4") + "," +dicomFile.ReadUInt16().ToString("x4");string VR = string.Empty;UInt32 Len = 0;//读取VR跟Len //对OB OW SQ 要做特殊处理 先置两个字节0 然后4字节值长度 //------------------------------------------------------这些都是在读取VR一步被阻断的情况 if (tag.Substring(0, 4) == "0002")//文件头 特殊情况 {VR = new string(dicomFile.ReadChars(2));if (VR == "OB" || VR == "OW" || VR == "SQ" || VR == "OF" || VR == "UT" || VR == "UN"){dicomFile.BaseStream.Seek(2, SeekOrigin.Current);Len = dicomFile.ReadUInt32();}elseLen = dicomFile.ReadUInt16();}else if (tag == "fffe,e000" || tag == "fffe,e00d" || tag == "fffe,e0dd")//文件夹标签 {VR = "**";Len = dicomFile.ReadUInt32();}else if (isExplicitVR == true)//有无VR的情况 {VR = new string(dicomFile.ReadChars(2));if (VR == "OB" || VR == "OW" || VR == "SQ" || VR == "OF" || VR == "UT" || VR == "UN"){dicomFile.BaseStream.Seek(2, SeekOrigin.Current);Len = dicomFile.ReadUInt32();}elseLen = dicomFile.ReadUInt16();}else if (isExplicitVR == false){VR = getVR(tag);//无显示VR时根据tag一个一个去找 真tm烦啊。 Len = dicomFile.ReadUInt32();}//判断是否应该读取VF 以何种方式读取VF //-------------------------------------------------------这些都是在读取VF一步被阻断的情况 byte[] VF = { 0x00 };if (tag == "7fe0,0010")//图像数据开始了 {pixDatalen = Len;pixDataOffset = dicomFile.BaseStream.Position;dicomFile.BaseStream.Seek(Len, SeekOrigin.Current);VR = "UL";VF = BitConverter.GetBytes(Len);}else if ((VR == "SQ" && Len == UInt32.MaxValue) || (tag == "fffe,e000" && Len == UInt32.MaxValue))//靠 遇到文件夹开始标签了 {if (enDir == false){enDir = true;folderData.Remove(0, folderData.Length);folderTag = tag;}else{leve++;//VF不赋值 }}else if ((tag == "fffe,e00d" && Len == UInt32.MinValue) || (tag == "fffe,e0dd" && Len == UInt32.MinValue))//文件夹结束标签 {if (enDir == true){enDir = false;}else{leve--;}}elseVF = dicomFile.ReadBytes((int)Len);string VFStr;VFStr = getVF(VR, VF);//----------------------------------------------------------------针对特殊的tag的值的处理 //特别针对文件头信息处理 if (tag == "0002,0000"){fileHeadLen = Len;fileHeadOffset = dicomFile.BaseStream.Position;}else if (tag == "0002,0010")//传输语法 关系到后面的数据读取 {switch (VFStr){case "1.2.840.10008.1.2.1\0"://显示little isLitteEndian = true;isExplicitVR = true;break;case "1.2.840.10008.1.2.2\0"://显示big isLitteEndian = false;isExplicitVR = true;break;case "1.2.840.10008.1.2\0"://隐式little isLitteEndian = true;isExplicitVR = false;break;default:break;}}for (int i = 1; i <= leve; i++)tag = "--" + tag;//------------------------------------数据搜集代码 if ((VR == "SQ" && Len == UInt32.MaxValue) || (tag == "fffe,e000" && Len == UInt32.MaxValue) || leve > 0)//文件夹标签代码 {folderData.AppendLine(tag + "(" + VR + "):" + VFStr);}else if (((tag == "fffe,e00d" && Len == UInt32.MinValue) || (tag == "fffe,e0dd" && Len == UInt32.MinValue)) && leve == 0)//文件夹结束标签 {folderData.AppendLine(tag + "(" + VR + "):" + VFStr);tags.Add(folderTag + "SQ", folderData.ToString());}elsetags.Add(tag, "(" + VR + "):" + VFStr);}}string getVR(string tag){switch (tag){case "0002,0000"://文件元信息长度 return "UL";break;case "0002,0010"://传输语法 return "UI";break;case "0002,0013"://文件生成程序的标题 return "SH";break;case "0008,0005"://文本编码 return "CS";break;case "0008,0008":return "CS";break;case "0008,1032"://成像时间 return "SQ";break;case "0008,1111":return "SQ";break;case "0008,0020"://检查日期 return "DA";break;case "0008,0060"://成像仪器 return "CS";break;case "0008,0070"://成像仪厂商 return "LO";break;case "0008,0080":return "LO";break;case "0010,0010"://病人姓名 return "PN";break;case "0010,0020"://病人id return "LO";break;case "0010,0030"://病人生日 return "DA";break;case "0018,0060"://电压 return "DS";break;case "0018,1030"://协议名 return "LO";break;case "0018,1151":return "IS";break;case "0020,0010"://检查ID return "SH";break;case "0020,0011"://序列 return "IS";break;case "0020,0012"://成像编号 return "IS";break;case "0020,0013"://影像编号 return "IS";break;case "0028,0002"://像素采样1为灰度3为彩色 return "US";break;case "0028,0004"://图像模式MONOCHROME2为灰度 return "CS";break;case "0028,0006"://颜色值排列顺序 可能骨头重建那个的显示就是这个问题 return "US";break;case "0028,0008"://图像的帧数 return "IS";break;case "0028,0010"://row高 return "US";break;case "0028,0011"://col宽 return "US";break;case "0028,0100"://单个采样数据长度 return "US";break;case "0028,0101"://实际长度 return "US";break;case "0028,0102"://采样最大值 return "US";break;case "0028,0103"://像素数据类型 return "US";break;case "0028,1050"://窗位 return "DS";break;case "0028,1051"://窗宽 return "DS";break;case "0028,1052":return "DS";break;case "0028,1053":return "DS";break;case "0040,0008"://文件夹标签 return "SQ";break;case "0040,0260"://文件夹标签 return "SQ";break;case "0040,0275"://文件夹标签 return "SQ";break;case "7fe0,0010"://像素数据开始处 return "OW";break;default:return "UN";break;}}string getVF(string VR, byte[] VF){if (VF.Length == 0)return "";string VFStr = string.Empty;if (isLitteEndian == false)//如果是big字节序 先把数据翻转一下 Array.Reverse(VF);switch (VR){case "SS":VFStr = BitConverter.ToInt16(VF, 0).ToString();break;case "US":VFStr = BitConverter.ToUInt16(VF, 0).ToString();break;case "SL":VFStr = BitConverter.ToInt32(VF, 0).ToString();break;case "UL":VFStr = BitConverter.ToUInt32(VF, 0).ToString();break;case "AT":VFStr = BitConverter.ToUInt16(VF, 0).ToString();break;case "FL":VFStr = BitConverter.ToSingle(VF, 0).ToString();break;case "FD":VFStr = BitConverter.ToDouble(VF, 0).ToString();break;case "OB":VFStr = BitConverter.ToString(VF, 0);break;case "OW":VFStr = BitConverter.ToString(VF, 0);break;case "SQ":VFStr = BitConverter.ToString(VF, 0);break;case "OF":VFStr = BitConverter.ToString(VF, 0);break;case "UT":VFStr = BitConverter.ToString(VF, 0);break;case "UN":VFStr = Encoding.Default.GetString(VF);break;default:VFStr = Encoding.Default.GetString(VF);break;}return VFStr;}}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace Dicom
{public partial class Main : Form{bool showTag = true;//tag/ 影像切换        DicomHandler handler;public Main(){InitializeComponent();UIswitch();}void UIswitch(){if (showTag) //显示标签 {textBox1.Visible = true;pictureBox1.Visible = false;toolStripButton3.Text = "显示图像";}else{textBox1.Visible = false;pictureBox1.Visible = true;toolStripButton3.Text = "显示标签";}if (backgroundWorker1.IsBusy){Bitmap loadImg = new Bitmap(200, 100);Graphics g = Graphics.FromImage(loadImg);g.DrawString("载入中,请稍后...", new Font(new FontFamily("Arial"), 15.0f), Brushes.Black, new PointF(0, 0));pictureBox1.Image = loadImg;pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;}else{if (handler != null && handler.gdiImg != null)    pictureBox1.Image = handler.gdiImg;pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;               }}private void toolStripButton1_Click(object sender, EventArgs e){if (backgroundWorker1.IsBusy){MessageBox.Show("影像载入中,请稍后...");return;}if (openFileDialog1.ShowDialog() != DialogResult.OK)return;string fileName = openFileDialog1.FileName;handler = new DicomHandler(fileName);handler.readAndShow(textBox1);this.Text = "DicomViewer-" + openFileDialog1.FileName;backgroundWorker1.RunWorkerAsync();UIswitch();}private void toolStripButton2_Click(object sender, EventArgs e){if (backgroundWorker1.IsBusy){MessageBox.Show("影像载入中,请稍后...");return;}if (saveFileDialog1.ShowDialog() != DialogResult.OK || handler == null || handler.gdiImg == null)return;handler.saveAs(saveFileDialog1.FileName);}private void toolStripButton3_Click(object sender, EventArgs e){showTag = !showTag;UIswitch();}private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e){if (handler.getImg())pictureBox1.Image = handler.gdiImg;}private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){UIswitch();}}
}
namespace TestForm
{partial class DicomForm{/// <summary>/// Required designer variable./// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// Clean up any resources being used./// </summary>/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows Form Designer generated code/// <summary>/// Required method for Designer support - do not modify/// the contents of this method with the code editor./// </summary>private void InitializeComponent(){this.toolStrip1 = new System.Windows.Forms.ToolStrip();this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();this.toolStripButton3 = new System.Windows.Forms.ToolStripButton();this.toolStripButton4 = new System.Windows.Forms.ToolStripButton();this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();this.textBox1 = new System.Windows.Forms.TextBox();this.pictureBox1 = new System.Windows.Forms.PictureBox();this.toolStrip1.SuspendLayout();((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();this.SuspendLayout();// // toolStrip1// this.toolStrip1.ImageScalingSize = new System.Drawing.Size(20, 20);this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this.toolStripButton1,this.toolStripButton2,this.toolStripButton3,this.toolStripButton4});this.toolStrip1.Location = new System.Drawing.Point(0, 0);this.toolStrip1.Name = "toolStrip1";this.toolStrip1.Size = new System.Drawing.Size(755, 27);this.toolStrip1.TabIndex = 0;this.toolStrip1.Text = "toolStrip1";// // toolStripButton1// this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta;this.toolStripButton1.Name = "toolStripButton1";this.toolStripButton1.Size = new System.Drawing.Size(47, 24);this.toolStripButton1.Text = "打 开";this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click);// // toolStripButton2// this.toolStripButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta;this.toolStripButton2.Name = "toolStripButton2";this.toolStripButton2.Size = new System.Drawing.Size(47, 24);this.toolStripButton2.Text = "保 存";this.toolStripButton2.Click += new System.EventHandler(this.toolStripButton2_Click);// // toolStripButton3// this.toolStripButton3.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;this.toolStripButton3.ImageTransparentColor = System.Drawing.Color.Magenta;this.toolStripButton3.Name = "toolStripButton3";this.toolStripButton3.Size = new System.Drawing.Size(73, 24);this.toolStripButton3.Text = "显示图像";this.toolStripButton3.Click += new System.EventHandler(this.toolStripButton3_Click);           // // openFileDialog1// this.openFileDialog1.FileName = "openFileDialog1";// // saveFileDialog1// this.saveFileDialog1.Filter = "Gif文件|*.gif|jpeg文件|*.jpg|bmp位图|*.bmp|可移植网络图形格式|*.png";// // backgroundWorker1// this.backgroundWorker1.DoWork += new    System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);// // textBox1// this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;this.textBox1.Location = new System.Drawing.Point(0, 27);this.textBox1.Margin = new System.Windows.Forms.Padding(5);this.textBox1.Multiline = true;this.textBox1.Name = "textBox1";this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;this.textBox1.Size = new System.Drawing.Size(755, 506);this.textBox1.TabIndex = 1;this.textBox1.WordWrap = false;// // pictureBox1// this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;this.pictureBox1.Location = new System.Drawing.Point(0, 27);this.pictureBox1.Margin = new System.Windows.Forms.Padding(5);this.pictureBox1.Name = "pictureBox1";this.pictureBox1.Size = new System.Drawing.Size(755, 506);this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;this.pictureBox1.TabIndex = 2;this.pictureBox1.TabStop = false;// // DicomForm// this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 20F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.ClientSize = new System.Drawing.Size(755, 533);this.Controls.Add(this.pictureBox1);this.Controls.Add(this.textBox1);this.Controls.Add(this.toolStrip1);this.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.Margin = new System.Windows.Forms.Padding(5);this.Name = "DicomForm";this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;this.Text = "DicomForm";this.toolStrip1.ResumeLayout(false);this.toolStrip1.PerformLayout();((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();this.ResumeLayout(false);this.PerformLayout();}#endregionprivate System.Windows.Forms.ToolStrip toolStrip1;private System.Windows.Forms.ToolStripButton toolStripButton1;private System.Windows.Forms.ToolStripButton toolStripButton2;private System.Windows.Forms.ToolStripButton toolStripButton3;private System.Windows.Forms.OpenFileDialog openFileDialog1;private System.Windows.Forms.SaveFileDialog saveFileDialog1;private System.ComponentModel.BackgroundWorker backgroundWorker1;private System.Windows.Forms.TextBox textBox1;private System.Windows.Forms.PictureBox pictureBox1;}
}

c#中将dicom文件格式转换成可读图片相关推荐

  1. Jpeg文件格式转换成bmp文件格式

    Jpeg文件格式转换成bmp文件格式为了简单,我将jpg图片原文件和转换后的bmp文件都直接存到内存的数组,这样不会涉及文件操作.将jpg文件转换成数组,并将数组存到文件中方便编译调用,我用的是C库文 ...

  2. 如何将AVI文件格式转换成MP4视频

    AVI格式是音视频交错格式,是Microsoft(即微软)推出作为Windows系统的多媒体格式.AVI格式是目前视频文件的主流格式,主要用于游戏录制,光盘文件,而且画质也不错,比较适合在电脑上观看: ...

  3. 如何将AVI文件格式转换成MP4视频 1

    AVI格式是音视频交错格式,是Microsoft(即微软)推出作为Windows系统的多媒体格式.AVI格式是目前视频文件的主流格式,主要用于游戏录制,光盘文件,而且画质也不错,比较适合在电脑上观看: ...

  4. 【引用】在Eclipse中将java Project转换成Dynamic Web Project

    编辑工程的.project文件: 添加 <nature>org.eclipse.wst.common.project.facet.core.nature</nature> &l ...

  5. Java中将inputstream输入流转换成byte[]字节数组

    Java中将inputstream输入流转换成byte[]字节数组 Java中的I/O机制都是基于数据流进行输入和输出的,将流转换成字节数组保存下来是数据流传输必不可少的一部分.转换的代码如下(在具体 ...

  6. oracle转换成字符型,Oracle中将Clob字段转换成字符串

    1. 利用dbms_lob.substr()方法可将对应字段转换成字符串如下 select dbms_lob.substr(content) from NEWS 该方法有个缺点,当content字段长 ...

  7. Python中将字节流文件转换成图片文件

    Python中将字节流文件转换成图片文件 import urllib3 import os #PIL图像处理标准库 from PIL import Image from io import Bytes ...

  8. 将AVI文件格式转换成MP4视频

    将AVI文件格式转换成MP4视频 一.在线转换https://cloudconvert.com/ 受网速影响,可能会转换失败,下载也较慢. (此网址功能强大,也可以进行各种格式的转换) 二.cmd命令 ...

  9. php实现视频转gif,在Linux上将视频转换成动态gif图片

    本文记录一下在linux上将视频转换成动态gif图片的方法. 首先,需要在Linux系统上安装FFmpeg,我会用这个工具去解压从视频中解压出视频帧. 下面的指令会解压出独立的视频帧,将它们保存为GI ...

最新文章

  1. Liferay 6.1 用maven 构建 service-builder的巨大BUG的修复
  2. 【linux草鞋应用编程系列】_2_ 环境变量和进程控制
  3. android加载时二级联动点击二级联动,Android实现联动下拉框二级地市联动下拉框功能...
  4. 服务器对程序员来说意味着什么,此文带你来了解
  5. redis设置为控制台打印日志
  6. 设计模式--享元模式实现C++
  7. sql 写query_为什么需要动态SQL
  8. JLupin Next Server乍一看
  9. 计算机网路【2】数据链路层
  10. java 字节输出流_Java IO详解(三)------字节输入输出流
  11. 增强火山图,要不要试一下?
  12. Google AJAX 搜索 API
  13. JavaScript基础学习(二)—JavaScript基本概念
  14. 如何让自己的email地址永久有效
  15. 轨迹规划-二次规划QP
  16. java两级缓存框架J2cache
  17. R语言实现单变量分析教程
  18. 纳兰容若最经典的20首诗词,每一首都是经典,读完眼泪掉下来
  19. python计算身份证最后一位数字代表什么_一个计算身份证号码校验位的Python小程序...
  20. No implementation found for void java接口不能跳转到实现类

热门文章

  1. nginx 配置 https双向认证
  2. C语言基础——字符串指针(指向字符串的指针)
  3. 联表查询和嵌套查询—读懂数据库仓储
  4. 非期望产出超效率SBM模型MATLAB代码
  5. 移动端安全通信的利器——端到端加密(E2EE)技术详解
  6. 未来天择计算机,三体吧关于计算机智能进化的讨论,拿来大家考虑一下
  7. @WebFilter和@Component一起使用导致urlPatterns不起作用
  8. zookeeper隐藏通道
  9. 惊爆:当Python代码遇到zip解压炸弹,未做防护的你后悔莫及!
  10. 国王3个囚犯戴帽子,帽子不是黑色就是白色---逻辑题。