image 合并

多页TIFF文件合并与拆分
部署运行你感兴趣的模型镜像
 
编译环境:VS 2003
语言:C#
描述:三tif文件:a.tif(two pages),b.tif(three pages),c.tif(two pages)
合并为net.tif(seven pages)
代码:
………………………………………
using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using System.Runtime.InteropServices;
 
namespace WF.lib
{
     ///<summary>
     /// ManagerImage 的摘要说明。
     ///</summary>
     public class ManagerImage// : IDisposable
     {
//       private Image image;
         public ManagerImage()
         {
              //
              // TODO: 在此处添加构造函数逻辑
              //
         }
 
//       public ManagerImage(string imageFileName)
//       {
//            image = Image.FromFile(imageFileName);
//       }
///<summary>
/// get file page number
///</summary>
///<param name="image"></param>
///<returns></returns>
         private int GetPageNumber(string imageFileName)
         {
              int imgPageNumber;
              Image image = Image.FromFile(imageFileName);
              Guid objGuid = image.FrameDimensionsList[0];
              FrameDimension objDimension = new FrameDimension(objGuid);
              //gets the total number of frames in the .tiff file
              imgPageNumber = image.GetFrameCount(objDimension);
              image.Dispose();
              return imgPageNumber;
         }
        
         ///<summary>
         /// Read the image base string,
         /// Assert(GetFileNameStartString(@"c:/test/abc.tif"),"abc")
         ///</summary>
         ///<param name="strFullName"></param>
         ///<returns>file name</returns>
         private string GetFileNameStartString(string strFullName)
         {
              //jason 2007-02-13 modify
              int posDot=strFullName.LastIndexOf(".");
              int posSlash=strFullName.LastIndexOf(@"/");
              //            int posDot=_ImageFileName.LastIndexOf(".");
              //            int posSlash=_ImageFileName.LastIndexOf(@"/");
              //            return _ImageFileName.Substring(posSlash+1,posDot-posSlash-1);
              return strFullName.Substring(posSlash+1,posDot-posSlash-1);
         }
 
        
         ///<summary>
         /// This function will output the image to a TIFF file with specific compression format
         ///</summary>
         ///<param name="outPutDirectory">The splited images' directory</param>
         ///<param name="format">The codec for compressing</param>
         ///<returns>splited file name array list</returns>
         public ArrayList SplitTiffImage(string outPutDirectory,EncoderValue format,string strFileName)
         {
              Image image;
              image = Image.FromFile(strFileName);
 
              string fileStartString=outPutDirectory+"//"+GetFileNameStartString(strFileName);
              ArrayList splitedFileNames=new ArrayList();
              try
              {
                   //jason 2007-012-13
                   int imagePageNum = GetPageNumber(strFileName);
                   Guid objGuid=image.FrameDimensionsList[0];
                   FrameDimension objDimension=new FrameDimension(objGuid);
 
                   //Saves every frame as a separate file.
                   Encoder enc=Encoder.Compression;
                   int curFrame=0;
                   for (int i=0;i<imagePageNum;i++)
                   {
                       image.SelectActiveFrame(objDimension,curFrame);
                       EncoderParameters ep=new EncoderParameters(1);
                       ep.Param[0]=new EncoderParameter(enc,(long)format);
                       ImageCodecInfo info=GetEncoderInfo("image/tiff");
                      
                       //Save the master bitmap
                       string fileName=string.Format("{0}{1}.tif",fileStartString,i.ToString());
                       image.Save(fileName,info,ep);
                       splitedFileNames.Add(fileName);
 
                       curFrame++;
                   }   
                   image.Dispose();
              }
              catch (Exception)
              {
                   throw;
              }
              return splitedFileNames;
         }
 
        
         ///<summary>
         /// This function will join the TIFF file with a specific compression format
         ///</summary>
         ///<param name="imageFiles">string array with source image files</param>
         ///<param name="outFile">target TIFF file to be produced</param>
         ///<param name="compressEncoder">compression codec enum</param>
         public void JoinTiffImages(string[] imageFiles,string outFile,EncoderValue compressEncoder)
         {
              try
              {
                   //If only one page in the collection, copy it directly to the target file.
                   if (imageFiles.Length==1)
                   {
                       File.Copy(imageFiles[0],outFile,true);
                       return;
                   }
 
                   //use the save encoder
                   Encoder enc=Encoder.SaveFlag;
 
                   EncoderParameters ep=new EncoderParameters(2);
                   ep.Param[0]=new EncoderParameter(enc,(long)EncoderValue.MultiFrame);
                   ep.Param[1] = new EncoderParameter(Encoder.Compression,(long)compressEncoder);
 
                   Bitmap pages=null;
                   int frame=0;
                   ImageCodecInfo info=GetEncoderInfo("image/tiff");
 
 
                   foreach(string strImageFile in imageFiles)
                   {
                       if(frame==0)
                       {
                            pages=(Bitmap)Image.FromFile(strImageFile);
 
                            //save the first frame
                            pages.Save(outFile,info,ep);
                       }
                       else
                       {
                            //save the intermediate frames
                            ep.Param[0]=new EncoderParameter(enc,(long)EncoderValue.FrameDimensionPage);
 
                            Bitmap bm=(Bitmap)Image.FromFile(strImageFile);
                            pages.SaveAdd(bm,ep);
                       }       
 
                       if(frame==imageFiles.Length-1)
                       {
                            //flush and close.
                            ep.Param[0]=new EncoderParameter(enc,(long)EncoderValue.Flush);
                            pages.SaveAdd(ep);
                       }
                       frame++;
                   }
              }
              catch (Exception)
              {
                   throw;
              }
              return;
         }
 
        
         ///<summary>
         /// This function will join the TIFF file with a specific compression format
         ///</summary>
         ///<param name="imageFiles">array list with source image files</param>
         ///<param name="outFile">target TIFF file to be produced</param>
         ///<param name="compressEncoder">compression codec enum</param>
         public void JoinTiffImages(ArrayList imageFiles,string outFile,EncoderValue compressEncoder)
         {
              try
              {
                   //If only one page in the collection, copy it directly to the target file.
                   if (imageFiles.Count==1)
                   {
                       File.Copy((string)imageFiles[0],outFile,true);
                       return;
                   }
 
                   //use the save encoder
                   Encoder enc=Encoder.SaveFlag;
 
                   EncoderParameters ep=new EncoderParameters(2);
                   ep.Param[0]=new EncoderParameter(enc,(long)EncoderValue.MultiFrame);
                   ep.Param[1] = new EncoderParameter(Encoder.Compression,(long)compressEncoder);
 
                   Bitmap pages=null;
                   int frame=0;
                   ImageCodecInfo info=GetEncoderInfo("image/tiff");
 
 
                   foreach(string strImageFile in imageFiles)
                   {
                       if(frame==0)
                       {
                            pages=(Bitmap)Image.FromFile(strImageFile);
 
                            //save the first frame
                            pages.Save(outFile,info,ep);
                       }
                       else
                       {
                            //save the intermediate frames
                            ep.Param[0]=new EncoderParameter(enc,(long)EncoderValue.FrameDimensionPage);
 
                            Bitmap bm=(Bitmap)Image.FromFile(strImageFile);
                            pages.SaveAdd(bm,ep);
                            bm.Dispose();
                       }       
 
                       if(frame==imageFiles.Count-1)
                       {
                            //flush and close.
                            ep.Param[0]=new EncoderParameter(enc,(long)EncoderValue.Flush);
                            pages.SaveAdd(ep);
                       }
 
                       frame++;
                   }
                   pages.Dispose();
              }
              catch (Exception ex)
              {
#if DEBUG
                   Console.WriteLine(ex.Message);
#endif
                   throw;
              }
             
              return;
         }
 
         ///<summary>
         /// Getting the supported codec info.
         ///</summary>
         ///<param name="mimeType">description of mime type</param>
         ///<returns>image codec info</returns>
         private ImageCodecInfo GetEncoderInfo(string mimeType)
         {
              ImageCodecInfo[] encoders=ImageCodecInfo.GetImageEncoders();
              for (int j=0;j<encoders.Length;j++)
              {
                   if (encoders[j].MimeType==mimeType)
                   {
                       return encoders[j];
                   }
              }
             
              throw new Exception( mimeType + " mime type not found in ImageCodecInfo" );
         }
 
        
         ///<summary>
         /// Return the memory steam of a specific page
         ///</summary>
         ///<param name="pageNumber">page number to be extracted</param>
         ///<returns>image object</returns>
         public Image GetSpecificPage(int pageNumber,string imageFileName)
         {
              Image image;
              image = Image.FromFile(imageFileName);
              MemoryStream ms=null;
              Image retImage=null;
              try
              {
                   ms=new MemoryStream();
                   Guid objGuid=image.FrameDimensionsList[0];
                   FrameDimension objDimension=new FrameDimension(objGuid);
 
                   image.SelectActiveFrame(objDimension,pageNumber);
                   image.Save(ms,ImageFormat.Bmp);
                  
                   retImage=Image.FromStream(ms);
                   image.Dispose();
                   return retImage;
              }
              catch (Exception)
              {
                   ms.Close();
                   retImage.Dispose();
                   throw;
              }
         }
///<summary>
/// get join iamge
/// Jason 2007-02-15
///</summary>
///<param name="imageFiles">file arraylist</param>
///<param name="splitedFileDir">split file temp dir</param>
///<param name="outputDir">join image directory</param>
///<returns>join image full name</returns>
         public string GetImage(ArrayList imageFiles, string splitedFileDir,string outputDir)
         {
              string rtnImageFile = "", outputFileName = "";
              ArrayList imageList = new ArrayList();
              //no file
              if(imageFiles.Count == 0)
              {
                   return "";
              }
              //get outputFileName
              outputFileName = GetFileNameStartString(imageFiles[0].ToString())+DateTime.Now.ToString("yyMMddHHss");
              rtnImageFile = outputDir+"//"+outputFileName+".tif";
              //delete null value
              for(int i=0;i<imageFiles.Count;i++)
              {
                   if(imageFiles[i].ToString().Equals(""))
                   {
                       imageFiles.RemoveAt(i);
                   }
              }
              //split image files
              //onel one file
              if(imageFiles.Count == 1)
              {
                   File.Copy(imageFiles[0].ToString(),rtnImageFile,true);
                   return rtnImageFile;
              }
              //more than one file
              for(int i=0;i<imageFiles.Count;i++)
              {
                   imageList.AddRange(SplitTiffImage(splitedFileDir,System.Drawing.Imaging.EncoderValue.CompressionNone,imageFiles[i].ToString()));
              }
              JoinTiffImages(imageList,rtnImageFile,System.Drawing.Imaging.EncoderValue.CompressionNone);
 
              return rtnImageFile;
         }
 
         #region IDisposable Members
         public void Dispose()
         {
//            //jason add
//            if(image != null)
//                 image.Dispose();
              System.GC.SuppressFinalize(this);
         }
         #endregion
        
     }
}
…………………………..
引用类:
ManagerImage manImage = new ManagerImage();
             
              ArrayList fileListA = new ArrayList();
//            ArrayList fileListB = new ArrayList();
              fileListA = manImage.SplitTiffImage(@"C:/itweb_src/WF/image/temp",System.Drawing.Imaging.EncoderValue.CompressionNone,@"C:/itweb_src/WF/image/body.tif");
              fileListA.AddRange(manImage.SplitTiffImage(@"C:/itweb_src/WF/image/temp",System.Drawing.Imaging.EncoderValue.CompressionNone,@"C:/itweb_src/WF/image/body_2.tif"));
//            fileListB = manImage.SplitTiffImage(@"C:/itweb_src/WF/image/temp",System.Drawing.Imaging.EncoderValue.CompressionNone,@"C:/itweb_src/WF/image/body_2.tif");
//            fileListA.AddRange(fileListB);
              string outFileName = @"C:/itweb_src/WF/image/new.tif";
//            string outFileNameB = @"C:/itweb_src/WF/image/newB.tif";
              manImage.JoinTiffImages(fileListA,outFileName,System.Drawing.Imaging.EncoderValue.CompressionNone);
引用方法二:
code in page:.............
string splitedFileDir = Application.StartupPath.ToString()+"//image//_temp";
string outPutDir = Application.StartupPath.ToString()+"//image//data";
string outputFileName = "";
ArrayList fileList = new ArrayList();
fileList.Add(......filename);
 
ManagerImage manImage = new ManagerImage();
outputFileName = manImage.GetImage(fileList,splitedFileDir,outPutDir);
//release the resource
manImage.Dispose();
fileList.Clear();
..........................................
 

您可能感兴趣的与本文相关的镜像

Dify

Dify

AI应用
Agent编排

Dify 是一款开源的大语言模型(LLM)应用开发平台,它结合了 后端即服务(Backend as a Service) 和LLMOps 的理念,让开发者能快速、高效地构建和部署生产级的生成式AI应用。 它提供了包含模型兼容支持、Prompt 编排界面、RAG 引擎、Agent 框架、工作流编排等核心技术栈,并且提供了易用的界面和API,让技术和非技术人员都能参与到AI应用的开发过程中

<think> 我们正在讨论的是i.MX8平台上使用`make image`命令合并文件的原理和文件格式。根据引用内容,我们可以从以下几个方面进行分析: 1. **构建系统背景**:引用[3]提到使用Yocto项目构建系统(特别是针对i.MX8平台)时,会生成多个镜像文件,包括文件系统镜像、内核镜像、设备树等。最终的可启动镜像(如SD卡镜像)是通过合并这些组件生成的。 2. **Makefile的作用**:引用[1]展示了在Linux内核构建系统中,通过Makefile定义构建目标(如zImage, uImage等)以及它们如何依赖于vmlinux(内核可执行文件)。构建过程中会调用相应的规则来生成这些镜像。 3. **镜像合并的具体步骤**:引用[2]提到了挂载镜像并替换内核和设备树文件的操作。这暗示了最终的启动镜像(如SD卡镜像)通常包含多个分区,其中第一个分区是FAT格式的启动分区(存放内核和设备树),第二个分区是根文件系统分区。 4. **最终镜像的格式**:引用[3]中列出了构建完成后生成的镜像文件,其中`*.rootfs.sdcard`就是可以直接写入SD卡的镜像。这种镜像通常是一个完整的磁盘映像,包含分区表(如MBR或GPT)和多个分区。 **原理分析**: - 当我们在i.MX8平台上执行`make image`(或类似命令)时,构建系统(如Yocto)会按照预先定义的规则,将不同的组件(U-Boot、内核、设备树、文件系统)合并成一个完整的、可以直接写入存储设备的镜像。 - 合并过程通常包括: 1. **创建磁盘映像文件**:分配一个固定大小的文件(例如,根据分区大小计算总大小)。 2. **分区**:使用分区工具(如`parted`或`fdisk`)在映像文件中创建分区表(通常是MBR或GPT),并创建多个分区(如一个FAT32格式的启动分区和一个ext4格式的根文件分区)。 3. **格式化分区**:将每个分区格式化为相应的文件系统。 4. **填充分区**: - 启动分区:复制U-Boot(可能位于特定位置,如未分区的区域或启动分区)、内核镜像(如zImageImage)、设备树文件(.dtb)以及其他启动所需的文件(如启动脚本)。 - 根文件系统分区:将构建好的根文件系统(如从`*.rootfs.ext4`或`*.rootfs.tar.bz2`解压或直接复制)复制到该分区。 5. **设置启动标志**:确保分区表中的启动标志正确(例如,设置启动分区为活动分区)。 6. **生成最终镜像**:完成上述步骤后,生成一个完整的磁盘映像文件(如`sdcard`镜像)。 **文件格式**: - 最终生成的镜像文件(如`*.rootfs.sdcard`)是一个**原始磁盘映像**(raw disk image),其格式与直接对SD卡进行完整磁盘转储得到的文件格式相同。 - 这种镜像可以直接使用`dd`命令写入SD卡:`sudo dd if=*.rootfs.sdcard of=/dev/sdX bs=4M`。 - 镜像内部结构: - **分区表**:位于镜像开头,描述分区的布局(起始扇区、大小、类型等)。 - **分区1**:通常是FAT32格式的启动分区,包含: - U-Boot(可能位于第一个分区之前,即没有分区的区域,具体取决于处理器和引导方式) - 内核镜像(如`zImage`或`Image`) - 设备树二进制文件(`.dtb`) - 其他启动文件(如U-Boot脚本、配置文件) - **分区2**:通常是ext4格式的根文件系统分区,包含完整的Linux根目录结构。 **引用支持**: - 引用[2]中提到的操作(挂载分区并替换内核和dtb)也印证了这种分区结构。用户将`.wic`文件(类似于`.sdcard`镜像)挂载为回环设备,然后挂载其两个分区(p1和p2),并替换内核和dtb文件[^2]。 - 引用[3]中列出的生成文件说明,其中`*.rootfs.sdcard`是可直接写入SD卡的镜像[^3]。 综上所述,`make image`命令(在Yocto项目中通常是构建整个镜像的目标)通过组合U-Boot、内核、设备树和根文件系统,并按照SD卡的分区布局将它们打包成一个完整的磁盘映像文件。这样生成的镜像可以直接烧录到SD卡中,用于启动i.MX8开发板。 §§相关问题§§ 1. 如何修改i.MX8的启动分区中的内核和设备树? 2. 在Yocto项目中,如何定制自己的SD卡镜像? 3. i.MX8的U-Boot通常位于镜像的什么位置? </think> ### i.MX8 中 `make image` 合并文件的原理及文件格式 #### 1. **合并原理** 在 i.MX8 的构建系统中,`make image` 命令通过以下步骤合并文件: - **依赖关系管理**:根据 Makefile 定义的依赖链(如引用[1]所示),确保先编译内核(`vmlinux`)、U-Boot 和设备树(DTB),再合并生成最终镜像[^1][^4]。 - **分区拼接**:将不同组件按预定义布局合并: - **U-Boot**:写入镜像起始位置(SD 卡未分区区域)。 - **内核与设备树**:放入 FAT 格式的启动分区(`/dev/loop0p1`)[^2]。 - **根文件系统**:复制到 ext4 格式的根分区(`/dev/loop0p2`)[^2][^3]。 - **镜像生成**:调用脚本(如 `scripts/Makefile.build`)将上述分区打包为单一磁盘镜像(如 `.sdcard` 文件)[^4]。 #### 2. **文件格式** 最终生成的镜像格式及组件: - **完整磁盘镜像**(如 `.rootfs.sdcard`): - 可直接烧录到 SD 卡,包含分区表和文件系统[^3]。 - 结构示例: ```plaintext +------------------+ <-- 0x0 | U-Boot (未分区区域) | +------------------+ <-- 分区表起始 | FAT 启动分区 (p1) | → 内核(zImage)、设备树(.dtb)、启动脚本 |------------------| | ext4 根分区 (p2) | → 根文件系统(从 .rootfs.ext4 复制) +------------------+ ``` - **关键组件格式**: - **内核**:压缩的 `zImage` 或原始 `Image` 文件[^3]。 - **设备树**:二进制 `.dtb` 文件(由 `.dts` 编译生成)。 - **根文件系统**:`.rootfs.ext4`(ext4 文件系统镜像)或 `.rootfs.tar.bz2`(压缩包)[^3]。 #### 3. **构建系统支持** - **Yocto 集成**:通过 BitBake 任务(如 `bitbake fsl-image-qt5`)自动化流程,复用缓存加速构建[^3]。 - **Makefile 机制**:顶层 Makefile 调用架构相关规则(如 `arch/arm/Makefile`),通过变量传递参数(如 `MACHINE=imx8mqevk`)[^1][^4]。 > **示例构建流程**: > ```bash > make linux-rootfs # 编译内核模块 > cp ./zImage /media/yin/boot # 替换内核 > make image # 生成合并后的SD卡镜像 > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值