using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
class Program
{
static void Main(string[] args)
{
byte[] bytes;
using (var td = new Bitmap(500, 500))
using (var lgb = new LinearGradientBrush(new Point(0, 0), new Point(td.Width, td.Height), Color.Red, Color.Green))
using (var g = Graphics.FromImage(td))
{
g.FillRectangle(lgb, 0, 0, td.Width, td.Height);
using (var ms = new MemoryStream())
{
td.Save(ms, ImageFormat.Jpeg);
bytes = ms.ToArray();
}
}
Image img;
using (var s = new TestStream(bytes))
{
img = Image.FromStream(s);
Console.WriteLine("Image.FromStream");
}
img.Save("a.jpg");
Console.WriteLine("Image.Save");
Console.ReadKey();
}
}
internal class TestStream : Stream
{
private readonly byte[] _Data;
private int _Position;
internal TestStream(byte[] array)
{
_Data = array;
}
public override bool CanRead
{
get
{
return true;
}
}
public override bool CanSeek
{
get
{
return true;
}
}
public override bool CanWrite
{
get
{
return false;
}
}
public override void Flush()
{
}
public override long Length
{
get
{
return _Data.Length;
}
}
public override long Position
{
get
{
return _Position;
}
set
{
_Position = Math.Min(Math.Max(0, (int)value), _Data.Length);
}
}
public override int Read(byte[] buffer, int offset, int count)
{
var l = Math.Min(count, _Data.Length - _Position);
if (l <= 0)
{
return 0;
}
Console.WriteLine("Stream.Read {0}, {1}", _Position, l);
Array.Copy(_Data, _Position, buffer, offset, l);
_Position += l;
return l;
}
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
{
case SeekOrigin.Begin:
Position = offset;
break;
case SeekOrigin.Current:
Position += offset;
break;
case SeekOrigin.End:
Position = _Data.Length + offset;
break;
}
return Position;
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uRHJhd2luZzsKdXNpbmcgU3lzdGVtLkRyYXdpbmcuRHJhd2luZzJEOwp1c2luZyBTeXN0ZW0uRHJhd2luZy5JbWFnaW5nOwp1c2luZyBTeXN0ZW0uSU87CgpjbGFzcyBQcm9ncmFtCnsKICAgIHN0YXRpYyB2b2lkIE1haW4oc3RyaW5nW10gYXJncykKICAgIHsKICAgICAgICBieXRlW10gYnl0ZXM7CiAgICAgICAgdXNpbmcgKHZhciB0ZCA9IG5ldyBCaXRtYXAoNTAwLCA1MDApKQogICAgICAgIHVzaW5nICh2YXIgbGdiID0gbmV3IExpbmVhckdyYWRpZW50QnJ1c2gobmV3IFBvaW50KDAsIDApLCBuZXcgUG9pbnQodGQuV2lkdGgsIHRkLkhlaWdodCksIENvbG9yLlJlZCwgQ29sb3IuR3JlZW4pKQogICAgICAgIHVzaW5nICh2YXIgZyA9IEdyYXBoaWNzLkZyb21JbWFnZSh0ZCkpCiAgICAgICAgewogICAgICAgICAgICBnLkZpbGxSZWN0YW5nbGUobGdiLCAwLCAwLCB0ZC5XaWR0aCwgdGQuSGVpZ2h0KTsKCiAgICAgICAgICAgIHVzaW5nICh2YXIgbXMgPSBuZXcgTWVtb3J5U3RyZWFtKCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRkLlNhdmUobXMsIEltYWdlRm9ybWF0LkpwZWcpOwogICAgICAgICAgICAgICAgYnl0ZXMgPSBtcy5Ub0FycmF5KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEltYWdlIGltZzsKICAgICAgICB1c2luZyAodmFyIHMgPSBuZXcgVGVzdFN0cmVhbShieXRlcykpCiAgICAgICAgewogICAgICAgICAgICBpbWcgPSBJbWFnZS5Gcm9tU3RyZWFtKHMpOwogICAgICAgICAgICBDb25zb2xlLldyaXRlTGluZSgiSW1hZ2UuRnJvbVN0cmVhbSIpOwogICAgICAgIH0KICAgICAgICBpbWcuU2F2ZSgiYS5qcGciKTsKICAgICAgICBDb25zb2xlLldyaXRlTGluZSgiSW1hZ2UuU2F2ZSIpOwoKICAgICAgICBDb25zb2xlLlJlYWRLZXkoKTsKICAgIH0KfQoKaW50ZXJuYWwgY2xhc3MgVGVzdFN0cmVhbSA6IFN0cmVhbQp7CiAgICBwcml2YXRlIHJlYWRvbmx5IGJ5dGVbXSBfRGF0YTsKICAgIHByaXZhdGUgaW50IF9Qb3NpdGlvbjsKCiAgICBpbnRlcm5hbCBUZXN0U3RyZWFtKGJ5dGVbXSBhcnJheSkKICAgIHsKICAgICAgICBfRGF0YSA9IGFycmF5OwogICAgfQoKICAgIHB1YmxpYyBvdmVycmlkZSBib29sIENhblJlYWQKICAgIHsKICAgICAgICBnZXQKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgb3ZlcnJpZGUgYm9vbCBDYW5TZWVrCiAgICB7CiAgICAgICAgZ2V0CiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIG92ZXJyaWRlIGJvb2wgQ2FuV3JpdGUKICAgIHsKICAgICAgICBnZXQKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIG92ZXJyaWRlIHZvaWQgRmx1c2goKQogICAgewogICAgfQoKICAgIHB1YmxpYyBvdmVycmlkZSBsb25nIExlbmd0aAogICAgewogICAgICAgIGdldAogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIF9EYXRhLkxlbmd0aDsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIG92ZXJyaWRlIGxvbmcgUG9zaXRpb24KICAgIHsKICAgICAgICBnZXQKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBfUG9zaXRpb247CiAgICAgICAgfQogICAgICAgIHNldAogICAgICAgIHsKICAgICAgICAgICAgX1Bvc2l0aW9uID0gTWF0aC5NaW4oTWF0aC5NYXgoMCwgKGludCl2YWx1ZSksIF9EYXRhLkxlbmd0aCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBvdmVycmlkZSBpbnQgUmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpCiAgICB7CiAgICAgICAgdmFyIGwgPSBNYXRoLk1pbihjb3VudCwgX0RhdGEuTGVuZ3RoIC0gX1Bvc2l0aW9uKTsKICAgICAgICBpZiAobCA8PSAwKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICBDb25zb2xlLldyaXRlTGluZSgiU3RyZWFtLlJlYWQgezB9LCB7MX0iLCBfUG9zaXRpb24sIGwpOwoKICAgICAgICBBcnJheS5Db3B5KF9EYXRhLCBfUG9zaXRpb24sIGJ1ZmZlciwgb2Zmc2V0LCBsKTsKICAgICAgICBfUG9zaXRpb24gKz0gbDsKICAgICAgICByZXR1cm4gbDsKICAgIH0KCiAgICBwdWJsaWMgb3ZlcnJpZGUgbG9uZyBTZWVrKGxvbmcgb2Zmc2V0LCBTZWVrT3JpZ2luIG9yaWdpbikKICAgIHsKICAgICAgICBzd2l0Y2ggKG9yaWdpbikKICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgU2Vla09yaWdpbi5CZWdpbjoKICAgICAgICAgICAgICAgIFBvc2l0aW9uID0gb2Zmc2V0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU2Vla09yaWdpbi5DdXJyZW50OgogICAgICAgICAgICAgICAgUG9zaXRpb24gKz0gb2Zmc2V0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU2Vla09yaWdpbi5FbmQ6CiAgICAgICAgICAgICAgICBQb3NpdGlvbiA9IF9EYXRhLkxlbmd0aCArIG9mZnNldDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICByZXR1cm4gUG9zaXRpb247CiAgICB9CgogICAgcHVibGljIG92ZXJyaWRlIHZvaWQgU2V0TGVuZ3RoKGxvbmcgdmFsdWUpCiAgICB7CiAgICAgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpOwogICAgfQoKICAgIHB1YmxpYyBvdmVycmlkZSB2b2lkIFdyaXRlKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkKICAgIHsKICAgICAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCk7CiAgICB9Cn0KCg==