Получить необработанные данные из экземпляра Image - PullRequest
4 голосов
/ 20 февраля 2010

Я получаю Image (фактически экземпляр класса Bitmap) из ресурсов, и (чтобы записать его в поток rtf) - мне нужны его необработанные данные.

Кроме того, метод Image.Save не может быть использован, потому что кажется, что он закрывает поток, в котором он сохраняется, и мне нужно добавить его в файл RTF. Я не хочу создавать новый поток, сохранять изображение в нем, а затем копировать его в поток RTF из-за проблем с производительностью.

1 Ответ

3 голосов
/ 22 марта 2011

Создайте поток фильтра, который проходит через поток, к которому вы хотите добавить, но не закрывает этот поток, когда он сам закрыт:

public class AppendingStream : Stream
{
    private readonly long _startPos;
    private readonly Stream _sink;
    public AppendingStream(Stream sink)
    {
        if(sink == null)
            throw new ArgumentNullException();
        if(!sink.CanWrite)
            throw new ArgumentException();
        _sink = sink;
        try
        {
            _startPos = sink.Position;
        }
        catch(NotSupportedException)
        {
            _startPos = -1;
        }
    }
    public override bool CanRead
    {
        get
        {
            return false;
        }
    }
    public override bool CanSeek
    {
        get
        {
            return _sink.CanSeek && _startPos != -1;
        }
    }
    public override bool CanTimeout
    {
        get
        {
            return _sink.CanTimeout;
        }
    }
    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override long Length
    {
        get
        {
            if(_startPos == -1)
                throw new NotSupportedException();
            return _sink.Length - _startPos;
        }
    }
    public override long Position
    {
        get
        {
            return _sink.Position - _startPos;
        }
        set
        {
            _sink.Position = value + _startPos;
        }
    }
    public override void Flush()
    {
        _sink.Flush();
    }
    public override int Read(byte[] buffer, int offset, int count)
    {
        throw new NotSupportedException();
    }
    public override int ReadByte()
    {
        throw new NotSupportedException();
    }
    public override long Seek(long offset, SeekOrigin origin)
    {
        if(origin == SeekOrigin.Begin)
            return _sink.Seek(offset + _startPos, SeekOrigin.Begin) - _startPos;
        else
            return _sink.Seek(offset, origin);
    }
    public override void SetLength(long value)
    {
        if(_startPos == -1)
            throw new NotSupportedException();
        _sink.SetLength(value + _startPos);
    }
    public override void Write(byte[] buffer, int offset, int count)
    {
        _sink.Write(buffer, offset, count);
    }
    public override void WriteByte(byte value)
    {
        _sink.WriteByte(value);
    }
}

Тогда у вас больше не будет проблемы с закрытием потока, поскольку это не имеет значения.

Биты, которые нужно учитывать при поиске новых позиций, заключаются в том, что некоторые форматы изображений записаны непоследовательным образом. Это не будет работать, если базовый поток не поддерживает его, но тогда это не сработает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...