Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.06.2008, 18:00   #1
inndim
Пользователь
 
Регистрация: 08.06.2008
Сообщений: 74
По умолчанию Проблема преобразование jpg в bmp через dll

Здравствуйте всем!
Пытаюсь написать dll которая будет конвертировать jpg в bmp, в delphi эта функция прекрасно работает, а вот экспортировать из dll не получается. Мне нужно чтобы из программы кликнув по кнопке, в dll передавался путь к файлу, а затем там этот jpg файл конвертировался в bmp и функция возвращала бы bitmap который я потом бы мог скопировать в Timage. Вот ниже привожу полностью код dll и самой программы, но увы почему-то не работает Помогите пожалуйста заставить всё это работать, я уже всю голову сломал. Да кстати SaveToClipboardFormat,LoadFromClipb oardFormat мне не подходят.

Dот код dll
Код:
library jpgtobmp;

uses
  SysUtils,Classes,jpeg,Graphics;

{$R *.res}
function convertjpgtobmp(p:String; bmp:TBitmap): TBitmap; stdcall;
var
JPEG: TJPEGImage;
begin
    JPEG := TJPEGImage.Create;
    JPEG.LoadFromFile(p);
    Bmp.Assign(JPEG);
    result:=bmp;
    JPEG.Free;
end;
exports convertjpgtobmp;
begin
end.
А вот код моей програмки, из которой я пытаюсь вызвать фунуцию из dll
Код:
unit Convert;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;
   function convertjpgtobmp(p: string; bmp:TBitmap):TBitmap; stdcall;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    OpenDialog1: TOpenDialog;
    Image1: TImage;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
function convertjpgtobmp; external 'jpgtobmp.dll';

{$R *.DFM}

procedure TForm1.Button2Click(Sender: TObject);
begin
close;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if opendialog1.Execute then
    convertjpgtobmp(opendialog1.FileName,image1.Picture.Bitmap);

end;
Заранее спасибо.
inndim вне форума Ответить с цитированием
Старый 23.06.2008, 19:39   #2
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

И Вам здравствуйте.
Модули VCL, подключаемые к dll имеют свои разделы инициализации, которые выполняются когда dll подгружается к приложению. По сути мы получаем два отдельных набора классов - для приложения и для DLL.
TBitMap.assign проверяет соответствие класса (as) и объект
TJPEGIMage(созданный в dll) отвергается как неопознанный.
Оба объекта должны быть созданы и использоваться или в dll или в приложении.
Лучшее, что Вы можете сделать - вернуть Handle of TBitMap:

Код:
function convertjpgtobmp(p:String):THandle; stdcall;
var JPEG: TJPEGImage;
    B:TBitMap;
begin
   B := TBitMap.Create;
   JPEG := TJPEGImage.Create;
   JPEG.LoadFromFile(p);
   B.Assign(JPEG);
   JPEG.Free;
   result := B.Handle;
   //B.free; 
   // Обратите внимание - объект не уничтожаем, чтобы не освободить Handle
   //Поэтому нужно предусмотреть отдельную процедуру для освобождения
end;
В приложении:
Код:
function convertjpgtobmp(p:String):THandle; stdcall; external 'jmptobmp.dll';
procedure TForm1.Button1Click(Sender: TObject);
var fileName:String;
    H:THandle;
    B : TBitMap;
begin
   fileName := 'alex.jpg';
   UniqueString(fileName);

   H := convertjpgtobmp(FileName);
   B := TBitMap.Create;
   B.Handle := H;
   Image1.Picture.Bitmap.Assign(B);
   ...
end;
Как видите, решение не очень элегантное.
Проще вообще отказаться от такого подхода и поместить эту функцию в приложение.
-------------------------------
Можно еще попробовать передать Canvas.Handle в dll и отрисовать полученный BitMap на канве.
-------------------------------
И не забывайте uses ShareMem.
alexBlack вне форума Ответить с цитированием
Старый 24.06.2008, 02:23   #3
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Можно как var параметры передать объект приемник и источник, а что вернет функция уже не важно, можно и процедуру сделать.

з.ы. Тут проблема не в конвертации а в передаче параметров. Так, как я написал, работает 100%.
А вот дельфи строки в DLL передавать не рекомендуется, PChar надо.

Приблизительно так: функция принимает из программы путь к файлу и ссылку на JpegImage, в функции создается локальный битмап, грузиться из файла, копируется (Assign) в тот JpegImage, битмап освобождается. Вернуть функция может результат успешно или нет завершилась.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 24.06.2008 в 02:38.
mutabor вне форума Ответить с цитированием
Старый 24.06.2008, 09:05   #4
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Цитата:
Сообщение от mutabor Посмотреть сообщение
Можно как var параметры передать объект приемник и источник, а что вернет функция уже не важно, можно и процедуру сделать.

з.ы. Тут проблема не в конвертации а в передаче параметров. Так, как я написал, работает 100%.
А вот дельфи строки в DLL передавать не рекомендуется, PChar надо.
mutabor, честно говоря не улавливаю Вашу мысль. Что не так с параметрами ? Отбросим пока передачу строк.

Цитата:
Приблизительно так: функция принимает из программы путь к файлу и ссылку на JpegImage, в функции создается локальный битмап, грузиться из файла, копируется (Assign) в тот JpegImage, битмап освобождается. Вернуть функция может результат успешно или нет завершилась.
Код:
// exe---------------
var G:TJPEGImage;
begin
   G := TJPEGImage.Create;
   try
      jpeg2bmp_1(G);
   finally
      G.free;
   end;
  ...
// dll----------------
procedure jpeg2bmp_1(G:TJPEGImage);
var B:TBitMap;
begin
   B := TBitMap.Create;
   G.loadFromFile('bulzano.jpg');
   B.Assign(G);
   B.free;
end;
Этот код дает Can't convert TIPEGImage to TBitMap.
Я думаю из-за несоответствия в B.assign при проверке класса (что-то вроде Source is TJPEGImage)

Вот если оба класса созданы в dll или в exe, то assign работает нормально. Например, так:

Код:
// exe ------
var G:TJPEGImage;
begin
   G := TJPEGImage.Create;
   try
      jpeg2bmp(image1.Picture.BitMap, G);
   finally
      G.free;
   end;
   ...
// dll--------
procedure jpeg2bmp(B:TBitMap; G:TJPEGImage);
begin
   G.loadFromFile('bulzano.jpg');
   B.Assign(G);
end;
Достаточно передать классовую ссылку и можно создавать объект в dll.
Например, так:

Код:
// exe--------
type TJPEGImageClass = class of TJPEGImage;
   procedure jpeg2bmp_2(B:TBitMap; C:TJPEGImageClass); external 'dll.dll' name 'jpeg2bmp_2';
   jpeg2bmp_2(image1.Picture.BitMap, TJPEGImage);
// dll---------
type
   TJPEGImageClass = class of TJPEGImage;
procedure jpeg2bmp_2(B:TBitMap; C:TJPEGImageClass);
var G:TJPEGImage;
begin
   G := C.Create;
   try
      G.loadFromFile('bulzano.jpg');
      B.Assign(G);
   finally
      G.free;
   end;
end;
alexBlack вне форума Ответить с цитированием
Старый 24.06.2008, 15:47   #5
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Цитата:
mutabor, честно говоря не улавливаю Вашу мысль. Что не так с параметрами ? Отбросим пока передачу строк.
Пардон, неясно выразился, тема называется "Проблема преобразование jpg в bmp через dll", вот я и говорю проблема тут не в преобразовании, а как лучше параметры в dll передать.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 24.06.2008, 18:24   #6
inndim
Пользователь
 
Регистрация: 08.06.2008
Сообщений: 74
По умолчанию

Спасибо всем за ответы, теперь примерно всё понял.
inndim вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Преобразование... prizrak1390 Общие вопросы Delphi 2 02.04.2008 11:24
Проблема соединения с MySQL через ODBC yakovlev87 БД в Delphi 1 27.08.2007 09:51
Преобразование типов Pronik Общие вопросы Delphi 2 12.06.2007 12:23