-
Здравствуйте, хочу написать программу - аналог Radmin, но не знаю, как организовать передачу изображения, точнее знаю - можно делать скрины, сжимать jpg и отсылать, но возможно есть способы для более быстрой передачи. Если у кого-нибудь есть исходники на Delphi по подобным задачам, буду за них признателен. В сети находил только на C++ :(
-
> хочу написать программу - аналог Radmin
А зачем ? Чем не устраивает куча существующих аналогичных программ, включая RAdmin ?
-
PascalC (25.11.08 12:22) более быстрой передачи не в передаче дело... а в ресурсоемкости сжатия... можно не весь экран передавать а только изменившуюся часть... а что изменилось это другая история
-
Ответ на аналогичный вопрос я нашел у себя в "быстрых ответах" код приема/передачи скриншота с jpg сжатием... постить?
-
> А зачем ? > Чем не устраивает куча существующих аналогичных программ, > включая RAdmin ?
Хочется расширить функционал этой кучи чтоб все в одном, а вообще -люблю изобретать велосипеды :)
> не в передаче дело... а в ресурсоемкости сжатия... > можно не весь экран передавать а только изменившуюся часть. > .. а что изменилось это другая история
Сравнить две картинки, вырезать измененные фрагменты, передать с координатами массив фрагментов? Не слишком большая нагрузка будет на проц? И потом, разные кусочки после сжатия и последующей склейки могут исказиться (если использовать jpg) Да и алгоритм поиска фрагментов пока не представляю, сколько их делать? а может передавать координаты/цвет каждого измененного пиксела?
Поэтому и спрашиваю, может у кого исходники на делфях завалялись, которые не жалко?
-
> Ответ на аналогичный вопрос я нашел у себя в "быстрых ответах" > код приема/передачи скриншота с jpg сжатием... постить?
Да, пожалуйста, пригодится.
-
> Хочется расширить функционал этой кучи чтоб все в одном
Что еще соббсно надо кроме интерактивного управления столом ?
> люблю изобретать велосипеды
Ну эт другой коленкор)
-
это сервер: program NetScreenServerCon;
uses
Windows,SysUtils,Classes,ScktComp,Graphics,Jpeg;
type
TSCThread=class(TServerClientThread)
private
Bitmap:TBitmap;
Jpeg:TJpegImage;
protected
procedure GrabScreen(Stream:TStream;const ImgSize:TPoint);
procedure ClientExecute; override;
public
constructor Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket);
destructor Destroy; override;
end;
constructor TSCThread.Create(CreateSuspended: Boolean;
ASocket: TServerClientWinSocket);
begin
Bitmap:=TBitmap.Create;
Jpeg:=TJpegImage.Create;
inherited;
end;
destructor TSCThread.Destroy;
begin
Jpeg.Free;
Bitmap.Free;
inherited;
end;
procedure TSCThread.GrabScreen(Stream:TStream;const ImgSize:TPoint);
var
Desktop:HWnd;
DesktopRect: TRect;
DesktopDC:HDc;
begin
Stream.Size:=0;
Desktop:=GetDesktopWindow;
GetWindowRect(Desktop,DesktopRect);
Bitmap.Height:=ImgSize.Y;
Bitmap.Width:=ImgSize.X;
DesktopDC:=GetWindowDC(Desktop);
try
Win32Check(StretchBlt(Bitmap.Canvas.Handle,0,0,Bitmap.Width,Bitmap.Height,
DesktopDC,DesktopRect.Left,DesktopRect.Top,DesktopRect.Right,DesktopRect.Bottom, SRCCOPY));
finally
ReleaseDC(Desktop,DesktopDC);
end;
Jpeg.Assign(Bitmap);
Jpeg.SaveToStream(Stream);
end;
procedure TSCThread.ClientExecute;
var
ScreenStream:TMemoryStream;
Buf:array[0..1023] of byte;
ImgSize:TPoint;
size:integer;
begin
while (not Terminated) and ClientSocket.Connected do
try
ScreenStream:=TMemoryStream.Create;
try
if ClientSocket.ReceiveBuf(ImgSize,SizeOf(ImgSize))<>SizeOf(ImgSize) then exit;
GrabScreen(ScreenStream,ImgSize);
ScreenStream.Position:=0;
size:=ScreenStream.Size;
ClientSocket.SendBuf(size,SizeOf(size));
while ScreenStream.Position<ScreenStream.Size do
begin
size:=ScreenStream.Read(Buf,SizeOf(Buf));
if ClientSocket.SendBuf(Buf,size)<>size then exit;
end;
finally
ScreenStream.Free;
end;
except
Terminate;
HandleException;
end;
end;
function Proc2Method(Code,Data:pointer):TMethod;
begin
result.Code:=Code;
result.Data:=Data;
end;
procedure GetThread(self,Sender: TObject; ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
SocketThread:=TSCThread.Create(true,ClientSocket);
SocketThread.Priority:=tpLower;
SocketThread.Resume;
end;
var Server:TServerSocket;
begin
Server:=TServerSocket.Create(nil);
try
Server.ServerType:=stThreadBlocking;
Server.OnGetThread:=TGetThreadEvent(Proc2Method(@GetThread,Server));
Server.Port:=1234;
Server.Active:=true;
while Server.Active do Sleep(100);
finally
Server.Free;
end;
end.
-
это клиент: unit ClientUnit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Forms,
ExtCtrls, StdCtrls, ScktComp, Controls;
type
TClientThread=class(TThread)
private
ClientSocket: TClientSocket;
LastUpdate:DWORD;
Bitmap:TBitmap;
protected
procedure UpdateScreen;
procedure Execute;override;
public
constructor Create(CreateSuspended: Boolean;const Address:string);
destructor Destroy;override;
end;
TForm1 = class(TForm)
Panel1: TPanel;
AddressEd: TEdit;
Button1: TButton;
Image: TImage;
procedure Button1Click(Sender: TObject);
private
ClientThread:TClientThread;
public
end;
var
Form1: TForm1;
implementation
uses math,Jpeg;
constructor TClientThread.Create(CreateSuspended: Boolean;const Address:string);
var i:integer;
begin
Bitmap:=TBitmap.Create;
ClientSocket:=TClientSocket.Create(nil);
ClientSocket.ClientType:=ctBlocking;
i:=pos(':',Address);
ClientSocket.Address:=copy(Address,1,i-1);
ClientSocket.Port:=StrToInt(copy(Address,i+1,MaxInt));
ClientSocket.Active:=true;
inherited Create(CreateSuspended);
end;
destructor TClientThread.Destroy;
begin
ClientSocket.Free;
Bitmap.Free;
inherited;
end;
procedure TClientThread.Execute;
var
Socket:TClientWinSocket;
ScreenStream:TMemoryStream;
ImgSize:TPoint;
Buf:array[0..1023] of byte;
size,ToRead:integer;
Jpeg:TJpegImage;
begin
Socket:=ClientSocket.Socket;
try
ScreenStream:=TMemoryStream.Create;
try
while Socket.Connected do
begin
ImgSize.X:=Form1.Image.Width;
ImgSize.Y:=Form1.Image.Height;
if Socket.SendBuf(ImgSize,SizeOf(ImgSize))<>SizeOf(ImgSize) then exit;
if Socket.ReceiveBuf(size,SizeOf(size))<>4 then exit;
if (Size<0) or (Size>maxInt-1) then exit;
ScreenStream.Size:=Size;
ScreenStream.Position:=0;
ToRead:=ScreenStream.Size-ScreenStream.Position;
ToRead:=Min(ToRead,Length(Buf));
while (ToRead>0) and Socket.Connected do
begin
Size:=Socket.ReceiveBuf(Buf,ToRead);
if Size<0 then exit;
ScreenStream.WriteBuffer(Buf,Size);
ToRead:=ScreenStream.Size-ScreenStream.Position;
ToRead:=Min(ToRead,Length(Buf));
end;
ScreenStream.Position:=0;
Jpeg:=TJpegImage.Create;
try
Jpeg.LoadFromStream(ScreenStream);
Bitmap.Assign(Jpeg);
finally
Jpeg.Free;
end;
Synchronize(UpdateScreen);
end;
finally
ScreenStream.Free;
end;
finally
Socket.Close;
end;
end;
procedure TClientThread.UpdateScreen;
var tick:DWORD;
begin
Form1.Image.Picture.Bitmap.Assign(Bitmap);
tick:=GetTickCount;
Form1.Image.Canvas.Brush.Style:=bsClear;
Form1.Image.Canvas.TextOut(1,1,Format('Разрешение: %d:%d, cкорость: %f кадр/сек',[Bitmap.Width,Bitmap.Height,1000/(tick-LastUpdate)]));
LastUpdate:=tick;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientThread:=TClientThread.Create(true,AddressEd.Text);
ClientThread.FreeOnTerminate:=true;
ClientThread.Priority:=tpLower;
ClientThread.Resume;
end;
end.
-
сжимать в Jpeg лучше с помощью Intel Jpeg Library. Она в разы быстрее.
-
спасибо
-
переписал под Intel Jpeg Library стало быстрее раза в два-три
-
Всё работает отлично!!! Не сталкивался с консольными приложениями, подскажите, что нужно дописать, чтобы консоль сервера исчезала\пряталась?
-
HITMAN (12.02.09 21:17) [12] {$apptype console} УБЕРИ :)
-
Благодарю! (пора заняться юзаньем консольных программ :)
-
> переписал под Intel Jpeg Library стало быстрее раза в два- > три
а как пользоваться этой библиотекой. Можешь выложить исходник?
-
-
> это клиент:unit ClientUnit;interfaceuses Windows, Messages, > SysUtils, Classes, Graphics, Forms, ExtCtrls, StdCtrls, > ScktComp, Controls;type TClientThread=class(TThread) private > ClientSocket: TClientSocket; LastUpdate:DWORD; Bitmap: > TBitmap; protected procedure UpdateScreen; procedure > Execute;override; public constructor Create(CreateSuspended: > Boolean;const Address:string); destructor Destroy;override; > end; TForm1 = class(TForm) Panel1: TPanel; AddressEd: > TEdit; Button1: TButton; Image: TImage; procedure > Button1Click(Sender: TObject); private ClientThread: > TClientThread; public end;var Form1: TForm1;implementationuses > math,Jpeg;{$R *.dfm}{ TClientThread }constructor TClientThread. > Create(CreateSuspended: Boolean;const Address:string);var > i:integer;begin Bitmap:=TBitmap.Create; ClientSocket:=TClientSocket. > Create(nil); ClientSocket.ClientType:=ctBlocking; i:=pos(': > ',Address); ClientSocket.Address:=copy(Address,1,i-1); > ClientSocket.Port:=StrToInt(copy(Address,i+1,MaxInt)); > ClientSocket.Active:=true; inherited Create(CreateSuspended); > end;destructor TClientThread.Destroy;begin ClientSocket. > Free; Bitmap.Free; inherited;end;procedure TClientThread. > Execute;var Socket:TClientWinSocket; ScreenStream:TMemoryStream; > ImgSize:TPoint; Buf:array[0..1023] of byte; size,ToRead: > integer; Jpeg:TJpegImage;begin Socket:=ClientSocket.Socket; > try ScreenStream:=TMemoryStream.Create; try > while Socket.Connected do begin ImgSize.X:=Form1. > Image.Width; ImgSize.Y:=Form1.Image.Height; > if Socket.SendBuf(ImgSize,SizeOf(ImgSize))<>SizeOf(ImgSize) > then exit; if Socket.ReceiveBuf(size,SizeOf(size))<>4 > then exit; if (Size<0) or (Size>maxInt-1) then exit; > ScreenStream.Size:=Size; ScreenStream.Position: > =0; ToRead:=ScreenStream.Size-ScreenStream.Position; > ToRead:=Min(ToRead,Length(Buf)); while (ToRead>0) > and Socket.Connected do begin Size:=Socket. > ReceiveBuf(Buf,ToRead); if Size<0 then exit; > ScreenStream.WriteBuffer(Buf,Size); ToRead: > =ScreenStream.Size-ScreenStream.Position; ToRead: > =Min(ToRead,Length(Buf)); end; ScreenStream. > Position:=0; Jpeg:=TJpegImage.Create; try > Jpeg.LoadFromStream(ScreenStream); Bitmap. > Assign(Jpeg); finally Jpeg.Free; end; > Synchronize(UpdateScreen); end; finally > ScreenStream.Free; end; finally Socket.Close; > end;end;procedure TClientThread.UpdateScreen;var tick: > DWORD;begin Form1.Image.Picture.Bitmap.Assign(Bitmap); > tick:=GetTickCount; Form1.Image.Canvas.Brush.Style:=bsClear; > Form1.Image.Canvas.TextOut(1,1,Format('Разрешение: %d: > %d, cкорость: %f кадр/сек',[Bitmap.Width,Bitmap.Height,1000/(tick- > LastUpdate)])); LastUpdate:=tick;end;procedure TForm1.Button1Click(Sender: > TObject);begin ClientThread:=TClientThread.Create(true, > AddressEd.Text); ClientThread.FreeOnTerminate:=true; ClientThread. > Priority:=tpLower; ClientThread.Resume;end;end.
в каком формате здесь вводится адресс машины 127:0:0:1 или другом?
-
все поняла... извините за глупый вопрос
-
> olchick © (03.06.09 12:23) [17] > >
> в каком формате здесь вводится адресс машины 127:0:0:1 или > другом?
Издеваетесь?
-
А исходных текстов с использованием intel...jpeg у когонибудь есть ?
-
какие тексты нужны? заголовки к интеловской библиотеке (IJL.pas) в комплекте с самой библиотекой... а там все просто JPEG_IO.pas:
procedure SaveBmpToJpegFile (Bitmap:TBitmap;const FileName:string; const Quality: integer); procedure SaveBmpToJpegStream(Bitmap:TBitmap;Stream: TMemoryStream; const Quality: integer); procedure LoadBmpFromJpegFile(Bitmap:TBitmap;const FileName:string; const SetPixelFormat:boolean=true; const Scale:TIJLScale=ijlFull); procedure LoadBmpFromJpegStream(bitmap: TBitmap; Stream:TMemoryStream; const SetPixelFormat:boolean=true; const Scale:TIJLScale=ijlFull);
-
kolobok776@ya.ru
Мне бы исходники просмотра удаленного рабочего стола , можно даже без управления , только чтобы процессор особо программа не нагрудала , может есть у кого , заранее благодарна ! kolobok776@ya.ru
-
А исходных текстов на все написанное выше может выложим ?
-
> PascalC (25.11.08 13:14) [4]
> а вообще -люблю изобретать велосипеды :)
> Поэтому и спрашиваю, может у кого исходники на делфях завалялись, > которые не жалко?
Как-то не вяжутся эти фразы. Или копи-паст уже стал называться изобретательством?
-
Света (20.02.10 12:32) [22] только чтобы процессор особо программа не нагрудала с этим как раз основная проблема: 1. основной напрягатор проца - сжатие картинки... 2. чтоб снять напрягу - нужно убрать сжатие 3. но без сжатия сетка колом встанет :) решение - передавать сжимая, но не каждый кадр, а только изменившуюся часть, а вот как определить что изменилось - другая задача и решается она по разному (от тупого сравнивания битмапов до драйвера дисплея)...
простой пример отправил на мыло
-
Ага спасибо получила . Буду думать как обуздать mirror driver/
-
кого интересует эта тема , пишите у меня усе получилось - на делфи тока!
-
сюда выкладывай... или линк на архив залитый на файл хостинг (типа iFolder.ru)
-
Поче6муто не крепится , завтра привреплю
-
uses Windows, SysUtils, Graphics, MultiMon;
type EMonitorCaptureException = class(Exception);
TCaptureContext = (ccActiveWindow,ccDesktopMonitor,ccActiveMonitor, ccSpecificMonitor,ccAllMonitors);
function MonitorCount : Integer;
procedure CaptureScreen(aCaptureContext : TCaptureContext; destBitmap : TBitmap;aMonitorNum : Integer = 1);
procedure CaptureRect(aCaptureRect : TRect;destBitMap : TBitmap); inline;
procedure CaptureDeviceContext(SrcDC: HDC;aCaptureRect : TRect;destBitMap : TBitmap); inline;
function GetMonInfoByIdx(MonIdx : Integer) : MONITORINFO;
implementation
type MonIndex = record Idx : Integer; Cnt : Integer; MonInfo : MONITORINFO; end; PMonIndex = ^MonIndex;
function MonCountCB(hm: HMONITOR; dc: HDC; r: PRect; l: LPARAM): Boolean; stdcall; begin inc(Integer(pointer(l)^)); result := true; end;
function MonitorCount : Integer; begin result := 0; EnumDisplayMonitors(0,nil,MonCountCB, Integer(@result)); end;
function MonInfoCB(hm: HMONITOR; dc: HDC; r: PRect; l: LPARAM): Boolean; stdcall; var MI : PMonIndex; begin MI := PMonIndex(pointer(l)); Inc(MI.Cnt); if MI.Cnt = MI.Idx then GetMonitorInfo(hm,@(MI.MonInfo)); result := true; end;
function GetMonInfoByIdx(MonIdx : Integer) : MONITORINFO; var MI : MonIndex; begin MI.MonInfo.cbSize := SizeOf(MI.MonInfo); MI.Idx := MonIdx; MI.Cnt := 0; EnumDisplayMonitors(0,nil,MonInfoCB, Integer(@MI)); result := MI.MonInfo; end;
procedure CaptureScreen(aCaptureContext : TCaptureContext; destBitmap : TBitmap;aMonitorNum : Integer); var DC : HDC; h : HWND; Mon : HMONITOR; MonInfo : MONITORINFO; lCapRect : TRect; begin Assert(Assigned(destBitMap)); h := 0; FillMemory(@lCapRect,SizeOf(TRect),0); dc := CreateDC('DISPLAY',nil,nil,nil); try case aCaptureContext of ccActiveWindow: begin h := GetForegroundWindow; GetWindowRect(h,lCapRect); end; ccDesktopMonitor: begin // This gets only the first/primary monitor lCapRect.Right := GetDeviceCaps (DC, HORZRES); lCapRect.Bottom := GetDeviceCaps (DC, VERTRES); end; ccActiveMonitor: begin h := GetForegroundWindow; Mon := MonitorFromWindow(h,MONITOR_DEFAULTTONEAREST); MonInfo.cbSize := SizeOf(MonInfo); GetMonitorInfo(Mon,@MonInfo); lCapRect := MonInfo.rcMonitor; end; ccSpecificMonitor: begin if (MonitorCount < aMonitorNum) or (aMonitorNum < 1) then raise EMonitorCaptureException.CreateFmt('Monitor Index out of Bounds [%d]',[aMonitorNum]); MonInfo := GetMonInfoByIdx(aMonitorNum); lCapRect := MonInfo.rcMonitor; end; ccAllMonitors: begin lCapRect.Right := GetSystemMetrics(SM_CXVIRTUALSCREEN); lCapRect.Bottom := GetSystemMetrics(SM_CYVIRTUALSCREEN); end; end; CaptureDeviceContext(dc,lCapRect,destBitmap); finally ReleaseDC(h, DC) ; end; end;
procedure CaptureDeviceContext(SrcDC: HDC;aCaptureRect : TRect;destBitMap : TBitmap); begin destBitmap.Width := aCaptureRect.Right - aCaptureRect.Left; destBitmap.Height := aCaptureRect.Bottom - aCaptureRect.Top; BitBlt(destBitmap.Canvas.Handle, 0, 0, destBitmap.Width, destBitmap.Height, SrcDC, aCaptureRect.Left, aCaptureRect.Top, SRCCOPY) ; end;
procedure CaptureRect(aCaptureRect : TRect;destBitMap : TBitmap); inline; var dc : HDC; begin dc := CreateDC('DISPLAY',nil,nil,nil); try CaptureDeviceContext(dc,aCaptureRect,destBitMap); finally ReleaseDC(0,dc); end; end; end.
Вот должно помочь!
-
> Света (15.03.10 12:28) [29] > Поче6муто не крепится , завтра привреплю > Света (08.04.10 11:15) [30] > uses > Windows, SysUtils, Graphics, MultiMon;
А вот и "завтра" наступило :)
-
"С пробужденьицем !" ))
-
Думал спостят mirror driver или какойнить fastBmpCompare/DifCutter, а оно все тоже только больше букаф
-
Да вот за границу с мужем ездили , вобшем у меня сорцы гднто на почте остались попробую найти среди спама , а на компе ничо не сохр . hddkill Славик решил испытать !
-
Славик это кто?
-
муж?
-
Славик - это заслуженный муж-испытатель заграниц
-
> Сергей М. (15.04.2010 12:54:37) [37]
Главный вредитель, заслуженый.
-
Он у меня вооще вредитель самый главный - я его люблю таким какой он есть .
-
Вот и ещё один дурдом к мировой помойке подключили и дерьмокодеров плодить начали...
-
Sam ti durdom2 , kak rabotat s vpn v Delphi ? P/s u mena s kodirovkoi oi beda !!!!
-
В упор не вижу в выложенных модулях IntelJpegLibrary функций
procedure SaveBmpToJpegStream(Bitmap:TBitmap;Stream: TMemoryStream; const Quality: integer); procedure LoadBmpFromJpegStream(bitmap: TBitmap; Stream:TMemoryStream; const SetPixelFormat:boolean=true; const Scale:TIJLScale=ijlFull);
ТОЛЬКО procedure SaveBmpToJpegFile (Bitmap:TBitmap;const FileName:string; const Quality: integer); procedure LoadBmpFromJpegFile(Bitmap:TBitmap;const FileName:string; const SetPixelFormat:boolean=true; const Scale:TIJLScale=ijlFull);
в JPEG_IO. И где они? кто там "переписал под ijl" без этих функций?
-
unit JPEG_IO;
interface
uses Windows, SysUtils, Classes, Graphics, IJL;
type
EIJLException = class(Exception);
type
TIJLScale=(ijlFull, ijlHalf, ijlQuarter, ijlEighth);
procedure SaveBmpToJpegFile (Bitmap:TBitmap;const FileName:string; const Quality: integer);
procedure SaveBmpToJpegStream(Bitmap:TBitmap;Stream: TMemoryStream; const Quality: integer);
procedure LoadBmpFromJpegFile(Bitmap:TBitmap;const FileName:string;
const SetPixelFormat:boolean=true; const Scale:TIJLScale=ijlFull);
procedure LoadBmpFromJpegStream(bitmap: TBitmap; Stream:TMemoryStream;
const SetPixelFormat:boolean=true; const Scale:TIJLScale=ijlFull);
implementation
procedure IJLCheck(Code:Integer);
begin
if Code<>IJL_OK then
raise EIJLException.Create(ijlErrorStr(Code));
end;
procedure SaveBmpToJpegFile(Bitmap:TBitmap;const FileName:string; const Quality: integer);
var
jcprops:TJPEG_CORE_PROPERTIES;
DIB: TDIBSection;
begin
FillChar(jcprops, SizeOf (jcprops), 0);
IJLCheck(ijlInit(@jcprops));
try
with jcprops do
begin
case bitmap.PixelFormat of
pf8bit:
begin
DIBChannels:=1;
DIBColor:=IJL_G;
end;
pf24bit:
begin
DIBChannels:=3;
DIBColor:=IJL_BGR;
end;
else raise EIJLException.Create('Cannot save bitmap as JPEG with specified PixelFormat');
end;
FillChar(DIB, SizeOf(DIB), 0);
Win32Check(GetObject(Bitmap.Handle, SizeOf(DIB),@DIB)<>0);
DIBBytes:= PByte(DIB.dsBm.bmBits);
DIBWidth := DIB.dsBm.bmWidth;
DIBHeight :=-DIB.dsBm.bmHeight;
DIBPadBytes:=((DIBWidth*DIBChannels+3) and -$04)-(DIBWidth*DIBChannels);
JPGFile := PChar(FileName);
JPGWidth := DIBWidth;
JPGHeight:= -DIBHeight;
JPGChannels:=3;
JPGColor := IJL_YCBCR;
jquality := quality;
end;
IJLCheck(ijlWrite(@jcprops, IJL_JFILE_WRITEWHOLEIMAGE));
finally
IJLCheck(ijlFree(@jcprops));
end;
end;
procedure SaveBmpToJpegStream(Bitmap:TBitmap;Stream: TMemoryStream; const Quality:integer);
var
jcprops:TJPEG_CORE_PROPERTIES;
DIB: TDIBSection;
begin
FillChar(jcprops, SizeOf (jcprops), 0);
IJLCheck(ijlInit(@jcprops));
try
with jcprops do
begin
case bitmap.PixelFormat of
pf8bit:
begin
DIBChannels:=1;
DIBColor:=IJL_G;
end;
pf24bit:
begin
DIBChannels:=3;
DIBColor:=IJL_BGR;
end;
else raise EIJLException.Create('Cannot save bitmap as JPEG with specified PixelFormat');
end;
FillChar(DIB, SizeOf(DIB), 0);
Win32Check(GetObject(Bitmap.Handle, SizeOf(DIB),@DIB)<>0);
DIBBytes:= PByte(DIB.dsBm.bmBits);
DIBWidth := DIB.dsBm.bmWidth;
DIBHeight :=-DIB.dsBm.bmHeight;
DIBPadBytes:=((DIBWidth*DIBChannels+3) and -$04)-(DIBWidth*DIBChannels);
Stream.Size:= Abs(DIBHeight*DIBWidth*DIBChannels);
JPGBytes := Stream.Memory;
JPGSizeBytes := Stream.Size;
JPGWidth := DIBWidth;
JPGHeight:= -DIBHeight;
JPGChannels:=3;
JPGColor := IJL_YCBCR;
jquality := quality;
end;
IJLCheck(ijlWrite(@jcprops, IJL_JBUFF_WRITEWHOLEIMAGE));
Stream.Size:=jcprops.JPGSizeBytes;
finally
IJLCheck(ijlFree(@jcprops));
end;
end;
const
ScaleMul:array[TIJLScale] of DWORD=(1,2,4,8);
procedure LoadBmpFromJpegFile(Bitmap:TBitmap;const FileName:string;
const SetPixelFormat:boolean=true; const Scale:TIJLScale=ijlFull);
const
ScaleFileIOType:array[TIJLScale] of TIJLIOTYPE=(IJL_JFILE_READWHOLEIMAGE,IJL_JFILE_READONEHALF,IJL_JFILE_READONEQUAR TER,IJL_JFILE_READONEEIGHTH);
var
jcprops: TJPEG_CORE_PROPERTIES;
DIB: TDIBSection;
begin
if not Assigned (Bitmap) then Exit;
FillChar(jcprops,SizeOf(jcprops),0);
IJLCheck(ijlInit(@jcprops));
try
jcprops.JPGFile:=PChar(FileName);
IJLCheck(ijlRead(@jcprops, IJL_JFILE_READPARAMS));
if (jcprops.JPGChannels<>1) and (jcprops.JPGChannels<>3) then
raise EIJLException.CreateFmt('Cannot load JPEG with %d Channels',[jcprops.JPGChannels]);
Bitmap.Width:=0;
Bitmap.Height:=0;
if SetPixelFormat then
begin
jcprops.DIBChannels:=jcprops.JPGChannels;
if jcprops.DIBChannels=1 then
Bitmap.PixelFormat:= pf8Bit
else
Bitmap.PixelFormat:= pf24Bit;
end else
begin
case Bitmap.PixelFormat of
pf8Bit: jcprops.DIBChannels:= 1;
pf24Bit: jcprops.DIBChannels:= 3;
else raise EIJLException.Create('Cannot load in bitmap with specified PixelFormat');
end;
end;
if jcprops.DIBChannels=1 then
jcprops.DIBColor:= IJL_G
else
jcprops.DIBColor:= IJL_BGR;
Bitmap.Width :=(jcprops.JPGWidth + ScaleMul[Scale]-1) div ScaleMul[Scale];
Bitmap.Height:=(jcprops.JPGHeight+ ScaleMul[Scale]-1) div ScaleMul[Scale];
FillChar(DIB, SizeOf (DIB), 0);
Win32Check(GetObject(Bitmap.Handle, SizeOf(DIB),@DIB)<>0);
jcprops.DIBBytes := PByte(DIB.dsBm.bmBits);
jcprops.DIBWidth := DIB.dsBm.bmWidth;
jcprops.DIBHeight:= -DIB.dsBm.bmHeight;
jcprops.DIBPadBytes:=((jcprops.DIBWidth*jcprops.DIBChannels+3) and -$04)-(jcprops.DIBWidth*jcprops.DIBChannels);
IJLCheck(ijlRead(@jcprops, ScaleFileIOType[Scale]));
finally
IJLCheck(ijlFree(@jcprops));
end;
Bitmap.Modified:=True;
end;
procedure LoadBmpFromJpegStream(bitmap: TBitmap; Stream:TMemoryStream;
const SetPixelFormat:boolean=true; const Scale:TIJLScale=ijlFull);
const
ScaleBuffIOType:array[TIJLScale] of TIJLIOTYPE=(IJL_JBUFF_READWHOLEIMAGE,IJL_JBUFF_READONEHALF,IJL_JBUFF_READONEQUAR TER,IJL_JBUFF_READONEEIGHTH);
var
jcprops: TJPEG_CORE_PROPERTIES;
DIB: TDIBSection;
begin
if not Assigned (Bitmap) then Exit;
FillChar(jcprops,SizeOf(jcprops),0);
IJLCheck(ijlInit(@jcprops));
try
jcprops.JPGBytes := PByte(Stream.Memory);
-
jcprops.JPGSizeBytes:= Stream.Size;
IJLCheck(ijlRead(@jcprops, IJL_JBUFF_READPARAMS));
if (jcprops.JPGChannels<>1) and (jcprops.JPGChannels<>3) then
raise EIJLException.CreateFmt('Cannot load JPEG with %d Channels',[jcprops.JPGChannels]);
Bitmap.Width:=0;
Bitmap.Height:=0;
if SetPixelFormat then
begin
jcprops.DIBChannels:=jcprops.JPGChannels;
if jcprops.DIBChannels=1 then
Bitmap.PixelFormat:= pf8Bit
else
Bitmap.PixelFormat:= pf24Bit;
end else
begin
case Bitmap.PixelFormat of
pf8Bit: jcprops.DIBChannels:= 1;
pf24Bit: jcprops.DIBChannels:= 3;
else raise EIJLException.Create('Cannot load in bitmap with specified PixelFormat');
end;
end;
if jcprops.DIBChannels=1 then
jcprops.DIBColor:= IJL_G
else
jcprops.DIBColor:= IJL_BGR;
Bitmap.Width :=(jcprops.JPGWidth + ScaleMul[Scale]-1) div ScaleMul[Scale];
Bitmap.Height:=(jcprops.JPGHeight+ ScaleMul[Scale]-1) div ScaleMul[Scale];
FillChar(DIB, SizeOf (DIB), 0);
Win32Check(GetObject(Bitmap.Handle, SizeOf(DIB),@DIB)<>0);
jcprops.DIBBytes := PByte(DIB.dsBm.bmBits);
jcprops.DIBWidth := DIB.dsBm.bmWidth;
jcprops.DIBHeight:= -DIB.dsBm.bmHeight;
jcprops.DIBPadBytes:=((jcprops.DIBWidth*jcprops.DIBChannels+3) and -$04)-(jcprops.DIBWidth*jcprops.DIBChannels);
IJLCheck(ijlRead(@jcprops, ScaleBuffIOType[Scale]));
finally
IJLCheck(ijlFree(@jcprops));
end;
Bitmap.Modified:=True;
end;
end.
-
Вау! У меня не вышло переписать IJL для Stream'а, но Slym ты мой спаситель!!!
-
Я так понял тема закрыта?
-
Чёта сплошные ошибки... Вопервых Slym не дописала : pfDevice: тип именно этот возвращается. Это вопервых... А вовторых при проверке: procedure IJLCheck(Code:Integer); begin if Code<>IJL_OK then raise EIJLException.Create(ijlErrorStr(Code)); end;
Хваленая билиотека постоянно генирирует код ошибки, прочитать его невозможно потому как на китайском... Народ кто как решил проблему? Или тут просто обсудили и все?
-
> Cola (07.01.11 15:02) [47]
> Вопервых Slym не дописала
Стыдно должно быть требовать ложку к миске дерьма. Дали ? Жуй и не жалуйся)
> Или тут просто обсудили и все?
Нет не все. Сейчас тебя начнем обсуждать)
-
Сергей М. у Вас что-т о по делу есть, если нет то флудите на других форумах.
Теперь по делу: Ошибку нашла, в соем коде по невнимательности... Проблемка другая, поток заработал но только вот изображение неверное передается... Оно построчно сдвинуто.... Кто с такой проблемкой встречался и как решил?
Для любителей пофлудить и поиздеваться над девушками - в игнор.
-
> Кто с такой проблемкой встречался и как решил? обычно решается вот так - > Ошибку нашла, в соем коде по невнимательности...
> Для любителей пофлудить и поиздеваться над девушками - в игнор. легко
|