为什么位图中的数据超出了范围?【JAVA教程】

!
也想出现在这里? 联系我们
信息

为什么位图中的数据超出了范围?,第1张

概述为什么位图中的数据超出了范围?

我为Skyrim创build了一个保存游戏pipe理器,并遇到了一个问题。 当我自己创buildSaveGame对象时,保存的位图部分正常工作。 然而,当我在一个循环中调用这个方法时,位图会带来一个错误的值,主要是一个与另一个保存游戏类似的值。

TL; DR – 为什么我的表单的列表框显示除了embedded图片之外的字符保存的正确信息? 而不是select正确的图片,它似乎select最后处理。 过程与通过打开的文件对话框select过程有何不同?

编辑:更新 – 我看着与每个SaveGame对象存储的位图,发现在scanDirectoryForSaves中创buildSaveGames时,不知怎的搞乱了它。 是否有位图的对象范围问题,并使用我不知道的字节指针?

这里是我的保存游戏对象的静态工厂的代码:

一个便携式的函数来创build一个从原始字节的BMP文件?

Bitmap.Save“通用错误”

c ++更改位图中的值

windows位图:BITMAPV5header和BITMAPINFO兼容?

简单的位图graphics在C + +?

public string name { get; private set; } public int SaveNumber { get; private set; } public int PictureWIDth { get; private set; } public int PictureHeight { get; private set; } public Bitmap Picture { get; private set; } public DateTime SaveDate { get; private set; } public string filename { get; private set; } public static SaveGame ReadSaveGame(string filename) { SaveGame save = new SaveGame(); save.filename = filename; byte[] file = file.ReadAllBytes(filename); int headerWIDth = BitConverter.ToInt32(file,13); save.SaveNumber = BitConverter.ToInt32(file,21); short nameWIDth = BitConverter.ToInt16(file,25); save.name = System.Text.EnCoding.UTF8.GetString(file,27,nameWIDth); save.PictureWIDth = BitConverter.ToInt32(file,13 + headerWIDth – 4); save.PictureHeight = BitConverter.ToInt32(file,13 + headerWIDth); save.readPictureData(file,13 + headerWIDth + 4,save.PictureWIDth,save.PictureHeight); save.SaveDate = DateTime.FromfileTime((long)BitConverter.ToUInt64(file,13 + headerWIDth – 12)); return save; } private voID readPictureData(byte[] file,int startIndex,int wIDth,int height) { IntPtr pointer = Marshal.UnsafeAddrOfPinnedArrayElement(file,startIndex); Picture = new Bitmap(wIDth,height,3 * wIDth,System.Drawing.Imaging.PixelFormat.Format24bppRgb,pointer); }

在我的表单中,我使用一种方法来读取某个目录中的所有保存文件,创buildSaveGame对象,并将它们存储在基于字符名称的字典中。

private Dictionary<string,List<SaveGame>> scanDirectoryForSaves(string directory) { Dictionary<string,List<SaveGame>> saves = new Dictionary<string,List<SaveGame>>(); DirectoryInfo info = new DirectoryInfo(directory); foreach (fileInfo file in info.Getfiles()) { if (file.name.Tolower().EndsWith(\”.ess\”) || file.name.Tolower().EndsWith(\”.bak\”)) { string filepath = String.Format(@\”{0}{1}\”,directory,file.name); SaveGame save = SaveGame.ReadSaveGame(filepath); if (!saves.ContainsKey(save.name)) { saves.Add(save.name,new List<SaveGame>()); } saves[save.name].Add(save); } } foreach (List<SaveGame> saveList in saves.Values) { saveList.sort(); } return saves; }

我将这些键添加到列表框中。 在列表框中select一个名称时,该表格上将显示该字符的最新保存。 每个字符的名称,date和其他字段都是正确的,但是位图是保存游戏图片的某个字符的变体。

我正在调用同样的方法来更新表单字段,从打开的文件对话框以及列表框中select一个保存。

private voID updateLabels(SaveGame save) { nameLabel.Text = \”name: \” + save.name; filenameLabel.Text = \”file: \” + save.filename; saveNumberLabel.Text = \”Save Number: \” + save.SaveNumber; saveDateLabel.Text = \”Save Date: \” + save.SaveDate; saveGamePictureBox.Image = save.Picture; saveGamePictureBox.Image = ScaleImage( saveGamePictureBox.Image,saveGamePictureBox.WIDth,saveGamePictureBox.Height); saveGamePictureBox.InvalIDate(); }

鼠标光标位图

何时处理graphics对象

在bitmap.h中,为什么bitmap_zero需要memset?

快速/简单的方法将windows位图旋转90度?

windows工具栏 – 控制button大小和填充

使用带IntPtr的构造函数创建Bitmap , IntPtr必须指向内存块,该块在Bitmap对象的生存Bitmap保持有效。 您有责任确保内存块不被移动或释放。

但是,您的代码正在传递指向file的IntPtr ,这是一个托管的字节数组。 由于ReadSaveGame返回后没有任何引用file ,垃圾收集器可以自由回收内存,并将其重用到下一个文件。 结果:损坏的位图。

虽然你可以通过用GCHandle在内存中固定数组来解决这个问题,但是让Bitmap管理自己的内存可能更简单也更安全。 首先创建一个空的Bitmap ,然后设置它的位:

private voID readPictureData(byte[] file,int height) { Bitmap bitmap = new Bitmap(wIDth,PixelFormat.Format24bppRgb); BitmapData data = bitmap.LockBits( new Rectangle(0,wIDth,height),ImageLockMode.writeonly,PixelFormat.Format24bppRgb); Marshal.copy(file,startIndex,data.Scan0,wIDth * height * 3); bitmap.UnlockBits(data); Picture = bitmap; }

总结

以上是内存溢出为你收集整理的为什么位图中的数据超出了范围?全部内容,希望文章能够帮你解决为什么位图中的数据超出了范围?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

© 版权声明
THE END
喜欢就支持一下吧
点赞57 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容