0

私が持っている質問は次のとおりです。

私はテクスチャファイルを持っていますが、世界中のテクスチャエディタで開くことはできません。そのファイルには、たとえば100個のテクスチャが含まれています。これらのテクスチャを取得する唯一の方法は、Hex Editor(Hex Workshopなど)でファイルを開き、「GBIX」文字列を見つけることです。そこから別のGBIXの開始までコピーを開始する「GBIX」文字列を見つけたら、新しいファイルを作成してそこに貼り付け、PVRとして保存すると、テクスチャが作成されます。ただし、ファイルには100個の「GBIX」文字列(100個のテクスチャ)があるため、これを100回実行する必要があります。さて、今、私はプログラミング、特にC#でいくつかのマイナーなスキルを持っていますが、文字列から文字列にコピーして新しいファイルに保存するプログラムを作成する方法がわかりません。

4

4 に答える 4

1

C では、これは非常に簡単です。

  1. ファイルをメモリにロードする
  2. ループ トラフ、パターンstrstr()の検索に使用GBIX
  3. 見つかったパターンごとに、次のパターン (またはファイルの終わり) を探します。
  4. 見つかった端ごとに、間の範囲を新しいバイナリ ファイルに書き出します。

高級言語ではさらに簡単になると思います。:)

あなたの質問は何ですか?

于 2012-10-04T09:37:42.953 に答える
1

Cでプログラミングできますか。それでは、次のことを行うだけです

1.open the file using `fopen()` in binary mode.
2.use a loop upto the end of file and search for the string what you want (strstr() to look for the GBIX pattern)-copied from unwind 
3.Then after finding each pattern get the position of the file pointer using ftell() and store it to a array of 100 integer(as 100 of texture you have ).
4.Then go to the first byte of file by using fseek().
5.Now you can use your array to find the location and read the whole data up to the next array element (do it in a loop upto 100 times).
6.then store this data or write it to another file(open a file in append mode and write there).

少しトリッキーだと思いますが、このアルゴリズムを使用してインターネットからコードを検索すると、間違いなくこれを実行できます。

于 2012-10-04T10:29:40.510 に答える
0

このコード例が役立つと思います。ファイルを解析する方法を示します。あなたがする必要があるのは、新しいファイルを作成することだけです..

using System;
using System.IO;
using Extensions;
using System.Drawing;

/* Archive Module */
namespace puyo_tools
{
    public class Images
    {
        /* Image format */
        private ImageClass Converter = null;
        public GraphicFormat Format  = GraphicFormat.NULL;
        private Stream Data          = null;
        private Bitmap imageData     = null;
        public string ImageName      = null;
        private string FileExt       = null;

        /* Image Object for unpacking */
        public Images(Stream dataStream, string dataFilename)
        {
            /* Set up our image information */
            Data = dataStream;

            ImageInformation(ref Data, out Format, out Converter, out ImageName, out FileExt);
        }

        /* Unpack image */
        public Bitmap Unpack()
        {
            return Converter.Unpack(ref Data);
        }
        public Bitmap Unpack(Stream palette)
        {
            return Converter.Unpack(ref Data, palette);
        }

        /* Pack image */
        public Stream Pack()
        {
            return Converter.Pack(ref imageData);
        }

        /* Output Directory */
        public string OutputDirectory
        {
            get
            {
                return (ImageName == null ? null : ImageName + " Converted");
            }
        }

        /* File Extension */
        public string FileExtension
        {
            get
            {
                return (FileExt == null ? String.Empty : FileExt);
            }
        }

        /* Get image information */
        private void ImageInformation(ref Stream data, out GraphicFormat format, out ImageClass converter, out string name, out string ext)
        {
            try
            {
                /* Let's check for image formats based on the 12 byte headers first */
                switch (data.ReadString(0x0, 12, false))
                {
                    case GraphicHeader.GIM: // GIM (Big Endian)
                    case GraphicHeader.MIG: // GIM (Little Endian)
                        format    = GraphicFormat.GIM;
                        converter = new GIM();
                        name      = "GIM";
                        ext       = ".gim";
                        return;
                }

                /* Ok, do special checks now */

                /* PVR file */
                if ((data.ReadString(0x0, 4) == GraphicHeader.GBIX && data.ReadString(0x10, 4) == GraphicHeader.PVRT && data.ReadByte(0x19) < 64) ||
                    (data.ReadString(0x0, 4) == GraphicHeader.PVRT && data.ReadByte(0x9) < 64))
                {
                    format    = GraphicFormat.PVR;
                    //converter = new PVR();
                    converter = null;
                    name      = "PVR";
                    ext       = ".pvr";
                    return;
                }

                /* GVR File */
                if ((data.ReadString(0x0, 4) == GraphicHeader.GBIX && data.ReadString(0x10, 4) == GraphicHeader.GVRT) ||
                    (data.ReadString(0x0, 4) == GraphicHeader.GCIX && data.ReadString(0x10, 4) == GraphicHeader.GVRT) ||
                    (data.ReadString(0x0, 4) == GraphicHeader.GVRT))
                {
                    format    = GraphicFormat.GVR;
                    converter = new GVR();
                    name      = "GVR";
                    ext       = ".gvr";
                    return;
                }

                /* SVR File */
                if ((data.ReadString(0x0, 4) == GraphicHeader.GBIX && data.ReadString(0x10, 4) == GraphicHeader.PVRT && data.ReadByte(0x19) > 64) ||
                    (data.ReadString(0x0, 4) == GraphicHeader.PVRT && data.ReadByte(0x9) > 64))
                {
                    format    = GraphicFormat.SVR;
                    converter = new SVR();
                    name      = "SVR";
                    ext       = ".svr";
                    return;
                }

                /* GMP File */
                if (data.ReadString(0x0, 8, false) == "GMP-200\x00")
                {
                    format    = GraphicFormat.GMP;
                    converter = new GMP();
                    name      = "GMP";
                    ext       = ".gmp";
                    return;
                }

                /* Unknown or unsupported compression */
                throw new GraphicFormatNotSupported();
            }
            catch (GraphicFormatNotSupported)
            {
                /* Unknown or unsupported image format */
                format     = GraphicFormat.NULL;
                converter  = null;
                name       = null;
                ext        = null;
                return;
            }
            catch
            {
                /* An error occured. */
                format     = GraphicFormat.NULL;
                converter  = null;
                name       = null;
                ext        = null;
                return;
            }
        }

        /* Image Information */
        public class Information
        {
            public string Name = null;
            public string Ext = null;
            public string Filter = null;

            public bool Unpack = false;
            public bool Pack  = false;

            public Information(string name, bool unpack, bool pack, string ext, string filter)
            {
                Name   = name;
                Ext    = ext;
                Filter = filter;

                Unpack = unpack;
                Pack   = pack;
            }
        }
    }

    /* Image Format */
    public enum GraphicFormat : byte
    {
        NULL,
        GIM,
        GMP,
        GVR,
        PVR,
        SVR,
    }

    /* Image Header */
    public static class GraphicHeader
    {
        public const string
            GBIX = "GBIX",
            GCIX = "GCIX",
            GIM  = ".GIM1.00\x00PSP",
            GMP  = "GMP-200\x00",
            GVRT = "GVRT",
            MIG  = "MIG.00.1PSP\x00",
            PVRT = "PVRT";
    }

    public abstract class ImageClass
    {
        /* Image Functions */
        public abstract Bitmap Unpack(ref Stream data);   // Unpack image
        public abstract Stream Pack(ref Bitmap data);     // Pack Image
        public abstract bool Check(ref Stream data);      // Check Image
        public abstract Images.Information Information(); // Image Information
        public virtual Bitmap Unpack(ref Stream data, Stream palette) // Unpack image (with external palette file)
        {
            return null;
        }
    }
}
于 2012-10-04T09:42:08.657 に答える
0

あなたはC#を使ったことがあると言います。これで、C# でこれを行う方法の大まかなアイデアが得られるはずですが、私自身はテストしていません。

始める前に、ファイルのサイズはどれくらいですか? ファイル全体がメモリに収まる場合、それを読み取る最も簡単な方法は を使用することですFile.ReadAllBytes。これにより、ファイル全体が 1 つの大きなバイト配列に読み込まれます。(ファイルのサイズがギガバイトの場合、一度にすべてをロードすることはできません。その場合は、ファイルを読み取るためのより高度な方法がありますが、まだそれらに進むことはしません。)

を使用File.ReadAllBytesしてファイルを読み取り、ファイルArray.IndexOf内でバイト 'G' を検索し、通常の配列インデックスを使用して他の文字をチェックできます。それらを見つけたら、 を使用して配列のチャンクをコピーし、 を使用Array.Copyしてファイルに保存できますFile.WriteAllBytes

あなたの質問は、ファイルの形式について完全に明確ではありません。あなたの説明から、それは次のようなものだと思います:

HEADERBYTESblahblahblahGBIXcontentcontentcontentGBIXmorecontentGBIXyetmorecontent

そして、これが破棄されることを期待しています:

HEADERBYTESblahblahblah

および 3 つの個別のファイルが作成されます。

GBIXcontentcontentcontent
GBIXmorecontent
GBIXyetmorecontent

したがって、最初の「GBIX」の前にテキストがある可能性があり、それを無視したいと考えています。最後の「GBIX」からファイルの最後までは、抽出したい適切なテクスチャであり、何も来ていません。その後。また、「GBIX」という文字がいずれかのテクスチャの途中に出現することはないと想定しています。その場合は、ファイル形式を実際に理解できるものを使用する必要があります。

using System;
using System.IO;

public class Program
{
    public static void WriteFile(int aFileIndex, byte[] sourceBytes, int firstByteIndex, int byteCount)
    {
        string filename = String.Format("output{0}.pvr", aFileIndex);
        byte[] outputBytes = new byte[byteCount];
        Array.Copy(sourceBytes, firstByteIndex, outputBytes, 0, byteCount);
        File.WriteAllBytes(filename, outputBytes);
    }

    public static void Main()
    {
        byte[] fileBytes = File.ReadAllBytes("inputfile");
        int filesOutput = 0;
        int startIndex = -1;
        int currentIndex = 0;
        for (;;)
        {
            int nextIndex = Array.IndexOf(fileBytes, (byte)'G', currentIndex);
            if (nextIndex == -1)
            {
                // There are no more ASCII 'G's in the file.
                break;
            }
            if (nextIndex + 4 >= fileBytes.Length)
            {
                // There aren't enough characters left in the file for this
                // to be an ASCII "GBIX" string.
                break;
            }
            if (fileBytes[nextIndex+1] == (byte)'B' &&
                fileBytes[nextIndex+2] == (byte)'I' &&
                fileBytes[nextIndex+3] == (byte)'X')
            {
                // Found ASCII "GBIX" at nextIndex. Output the previous
                // complete file, if there is one.
                if (startIndex != -1)
                {
                    Write(filesOutput, fileBytes, startIndex, nextIndex - startIndex);
                }
                filesOutput += 1;
                startIndex = nextIndex;
            }
            currentIndex = nextIndex + 1;
        }
        if (startIndex != -1)
        {
            WriteFile(filesOutput, fileBytes, startIndex, fileBytes.Length - startIndex);
        }
    }
}
于 2012-10-04T15:03:09.630 に答える