В ответ на ваш другой вопрос приведен код для загрузки файла JPG в растровое изображение и условного применения исправления к полученному растровому изображению.Обратите внимание, что это работает для вашего изображения Brown.JPG, но я понятия не имею, что находится в этих первых 18 байтах, поэтому я понятия не имею, будет ли это работать долго или нет.Я лично предпочел бы использовать готовую, известную в работе, широко используемую библиотеку.В качестве альтернативы я бы использовал идею Дэвида использовать WIC, если он доступен, и вернуться к этому стилю хакерского кода, если он недоступен.
Вот код полный , чтобы вы могли увидеть все использованные модули,Форма ожидает только одну TImage
с именем Image1
в форме, поэтому вы можете сначала создать свою форму, поместить туда TImage
, а затем переключиться в представление исходного кода и скопировать и вставить мой код поверх кода, созданного в Delphi..
Как работает код:
Код открывает файл с изображением JPG и загружает его в TJpgImage.Затем он сравнивает первые 18 байтов файла с известным маркером.Если есть совпадение, оно применяет преобразование к каждому пикселю производимого растрового изображения.Поскольку записать фактические константы маркера сложно, есть подпрограмма (CopyConstToClipboard), которая берет байты из файла, преобразует их в константу в стиле Delphi и копирует ее в буфер обмена.Когда вы найдете новый файл, который не работает, вы должны использовать эту процедуру для подготовки новой константы.
Фактический код:
unit Unit9;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Jpeg, Clipbrd;
type
TForm9 = class(TForm)
Image1: TImage;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form9: TForm9;
implementation
{$R *.dfm}
type
TRGB_Pixel = packed record
B1: Byte;
B2: Byte;
B3: Byte;
end;
TScanLine = array[0..(System.MaxInt div SizeOf(TRGB_Pixel))-1] of TRGB_Pixel;
PScanLine = ^TScanLine;
procedure CopyConstToClipboard(const FB:array of byte);
var s: string;
i: Integer;
begin
s := 'Name: array[0..' + IntToStr(High(FB)) + '] of Byte = ($' + IntToHex(FB[0], 2);
for i:=1 to High(FB) do
s := s + ', $' + IntToHex(FB[i],2);
s := s + ');';
Clipboard.AsText := s;
end;
function LoadJpegIntoBitmap(const FileName:string): TBitmap;
var F: TFileStream;
Jpg: TJPEGImage;
FirstBytes:array[0..17] of Byte;
y,x: Integer;
ScanLine: PScanLine;
const Marker_1: array[0..17] of Byte = ($FF, $D8, $FF, $EE, $00, $0E, $41, $64, $6F, $62, $65, $00, $64, $00, $00, $00, $00, $00);
procedure SwapBytes(var A, B: Byte);
var T: Byte;
begin
T := A;
A := B;
B := T;
end;
begin
F := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Jpg := TJPEGImage.Create;
try
Jpg.LoadFromStream(F);
F.Position := 0;
F.Read(FirstBytes, SizeOf(FirstBytes));
// CopyConstToClipboard(FirstBytes); // Uncomment this to copy those first bytes to cliboard
Result := TBitmap.Create;
Result.Assign(Jpg);
if (Result.PixelFormat = pf24bit) and CompareMem(@Marker_1, @FirstBytes, SizeOf(FirstBytes)) then
begin
for y:=0 to Result.Height-1 do
begin
ScanLine := Result.ScanLine[y];
for x:=0 to Result.Width-1 do
begin
SwapBytes(ScanLine[x].B1, ScanLine[x].B3);
end;
end;
end;
finally Jpg.Free;
end;
finally F.Free;
end;
end;
procedure TForm9.FormCreate(Sender: TObject);
var B: TBitmap;
begin
B := LoadJpegIntoBitmap('C:\Users\Cosmin Prund\Downloads\ABrownImage.jpg');
try
Image1.Picture.Assign(B);
finally B.Free;
end;
end;
end.