0

分離されたストレージに画像を保存するアプリケーションをSilverlightで作成しています。隔離されたストレージに画像を保存できましたが、画像を読み込んで表示するのに問題があります。

コードは次のとおりです。

public partial class MainPage : UserControl
    {

    private const string ImageName = "google1.png";

    public MainPage()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {           
        WriteableBitmap bitmap = new WriteableBitmap(saveImage, new TransformGroup());
        loadedImage.Source = bitmap;
        imageToStore(saveBuffer(bitmap), ImageName);

        MessageBox.Show("saved");

    }

    public void imageToStore(byte[] buffer, string filename)
    {
        using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())   

        {

            IsolatedStorageFileStream s = new IsolatedStorageFileStream(filename, FileMode.Create, iso);
            Int64 freeSpace = iso.AvailableFreeSpace;      
            Int64 needSpace = 20971520; // 20 MB in bytes      
            if (freeSpace < needSpace)     
              {           
                if (!iso.IncreaseQuotaTo(iso.Quota + needSpace))        
                   {                MessageBox.Show("User rejected increase spacerequest");       


                    }      
            else            {                MessageBox.Show("Space Increased");         

                            }          

                }


            using (StreamWriter writer = new StreamWriter(s))
            {
                writer.Write(buffer);
            }

        }          
    }
    private static byte[] saveBuffer(WriteableBitmap bitmap)
    {


        long matrixSize = bitmap.PixelWidth * bitmap.PixelHeight;

        long byteSize = matrixSize * 4 + 4;

        byte[] retVal = new byte[byteSize];

        long bufferPos = 0;

        retVal[bufferPos++] = (byte)((bitmap.PixelWidth / 256) & 0xff);
        retVal[bufferPos++] = (byte)((bitmap.PixelWidth % 256) & 0xff);
        retVal[bufferPos++] = (byte)((bitmap.PixelHeight / 256) & 0xff);
        retVal[bufferPos++] = (byte)((bitmap.PixelHeight % 256) & 0xff);


        return retVal;

    }

    private void button2_Click(object sender, RoutedEventArgs e)
    {
        byte[] buffer = _LoadIfExists(ImageName);
        loadedImage.Source = _GetImage(buffer);
        MessageBox.Show("loaded");
    }


    private static byte[] _LoadIfExists(string fileName)
    {
        byte[] retVal;

        using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
        {
            if (iso.FileExists(fileName))
            {
                using (IsolatedStorageFileStream stream = iso.OpenFile(fileName, FileMode.Open))
                {
                    retVal = new byte[stream.Length];
                    stream.Read(retVal, 0, retVal.Length);
                    stream.Close();
                }
            }
            else
            {
                retVal = new byte[0];
            }
        }
        return retVal;
    }

        private static WriteableBitmap _GetImage(byte[] buffer)
    {
        int width = buffer[0] * 256 + buffer[1];
        int height = buffer[2] * 256 + buffer[3];

        long matrixSize = width * height;


            //this is the section where Exception of type 'System.OutOfMemoryException' was thrown.
        WriteableBitmap retVal = new WriteableBitmap(width, height);

        int bufferPos = 4;

        for (int matrixPos = 0; matrixPos < matrixSize; matrixPos++)
        {
            int pixel = buffer[bufferPos++];
            pixel = pixel << 8 | buffer[bufferPos++];
            pixel = pixel << 8 | buffer[bufferPos++];
            pixel = pixel << 8 | buffer[bufferPos++];
            retVal.Pixels[matrixPos] = pixel;
        }

        return retVal;
}}}

皆さんが私を助けてくれることを願っています。どうもありがとう。

4

1 に答える 1

1

基本的に、Silverlight を使用してイメージを管理するのは簡単なことではありません。

アプリケーションを実行するコンピューターの能力がどうであれ、ブラウザによって制限されます。ブラウザは、セキュリティにより、アプリケーション専用の RAM とプロセッサを制限します。(お使いのブラウザのバージョンにもよりますが、およそ 1Go 程度の使用 RAM です)。

唯一の解決策は、メモリ管理を最適化することです (マネージ言語では常に注意が必要です...)。

  • あなたの新しい指示を避けるようにしてください(最大のオブジェクトを再利用してください)

  • オブジェクトが不要になったらすぐに、そのポインターを null に設定します (ガベージ コレクターによって収集されるように解放しておくため)。

  • 最後のオプションとして、戦略的な場所で GC.Collect() を呼び出すようにしてください (ただし、頻繁に呼び出すとパフォーマンスが劇的に低下する可能性があるため、十分に注意してください)。

于 2013-02-07T08:35:46.567 に答える