前言
dcm转mp4实现思路为:先把dcm转换为图片,然后把图片转换成视频。
一、操作步骤
1.环境搭建
1.1 安装abp.vnext 脚手架
dotnet tool install -g Volo.Abp.Cli
1.2 创建基于Abp.vnext的控制台的项目
abp new Ocean.DcmToMp4 -t console --version 6.0.0
1.3 创建完成项目结构如下
1.4 dcm转图片
通过nuget 安装fo-dicom.core和 SkiaSharp;
dcm转图片核心代码
/// <summary>
/// dcm转图片
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
private string DcmToImgs(string filename)
{
var dcmFile = DicomFile.Open(filename);
int cols = dcmFile.Dataset.GetSingleValue<int>(DicomTag.Columns);
int rows = dcmFile.Dataset.GetSingleValue<int>(DicomTag.Rows);
var frames = dcmFile.Dataset.GetSingleValue<int>(DicomTag.NumberOfFrames);
var image = new DicomImage(dcmFile.Dataset);
var frameRate = GetFrameRate(dcmFile.Dataset);
var imgsPath = "imgs";
if (Directory.Exists(imgsPath))
{
Directory.GetFiles(imgsPath).ToList().ForEach(File.Delete);
}
else
{
Directory.CreateDirectory(imgsPath);
}
for (int frame = 0; frame < frames; frame++)
{
var iImage = image.RenderImage(frame);
var imageBytes = iImage.AsBytes();
//var skData = SKData.CreateCopy(imageBytes);
using (FileStream fs = new FileStream($"{imgsPath}/img{frame}.jpg", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
SKBitmap bitmap = new();
GCHandle gcHandle = GCHandle.Alloc(imageBytes, GCHandleType.Pinned);
SKImageInfo info = new(cols, rows, SKColorType.Bgra8888, SKAlphaType.Premul);
IntPtr ptr = gcHandle.AddrOfPinnedObject();
int rowBytes = info.RowBytes;
bitmap.InstallPixels(info, ptr, rowBytes, delegate { gcHandle.Free(); });
bitmap.Encode(SKEncodedImageFormat.Jpeg, 100).SaveTo(fs);
}
}
return ImgsToMp4(cols, rows, frameRate, imgsPath);
}
1.5 图片转mp4
图片转视频采用ffmpeg,核心代码如下
/// <summary>
/// 图片转视频
/// </summary>
/// <param name="cols"></param>
/// <param name="rows"></param>
/// <param name="frameRate"></param>
/// <param name="imgPath"></param>
private string ImgsToMp4(int cols,int rows,int frameRate,string imgPath)
{
string ffmpegPath = "/usr/bin/ffmpeg";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
ffmpegPath = "/usr/bin/ffmpeg";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
ffmpegPath = AppDomain.CurrentDomain.BaseDirectory + "Ffmpeg\\bin\\ffmpeg.exe";
}
var width = cols;
var height = rows;
var outputFileName = Guid.NewGuid().ToString("N") + ".mp4";
imgPath = imgPath + @"/img%d.jpg";
Log.Information("imgPath:" + imgPath);
string command = $"-r {frameRate} -f image2 -s {width}x{height} -i {imgPath} -vcodec libx264 -crf 15 -pix_fmt yuv420p {outputFileName}";
Process p = new Process();
p.StartInfo.FileName = ffmpegPath;
p.StartInfo.Arguments = command;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.ErrorDataReceived += new DataReceivedEventHandler((s, message) =>
{
Log.Information(message.Data);
});
p.Start();//启动线程
p.BeginErrorReadLine();//开始异步读取
p.WaitForExit();//阻塞等待进程结束
p.Close();//关闭进程
p.Dispose();//释放资源
return outputFileName;
}
总结
以上就是dcm转mp4的核心代码,下一章将继续讲解如何把项目发布到docker中,谢谢大家。