Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.04.09;
Скачать: CL | DM;

Вниз

Не могу понять, в чем ошибка.   Найти похожие ветки 

 
DmitryNekl   (2006-03-23 12:26) [0]

Буду признателен за помощь.
Хочу сохранить картинку jpeg в базу.
База - компонент ClientDataSet (name="photos").
Код создания формы:
 photos.FileName:=ExtractFilePath(Application.ExeName)+"photos.cds";
 if not FileExists(photos.FileName) then
 begin
   photos.FieldDefs.Clear;
   photos.FieldDefs.Add("id", ftInteger);
   photos.FieldDefs.Add("photo", ftBlob);
   photos.CreateDataSet;
 end;
 photos.Open;
 photos.SaveToFile();

Затем пытаюсь сохранить картинку:
 if Image1.Picture.Graphic is TJPegImage then
 begin
   bs:=TBlobStream.Create(TBlobField(photos.FieldByName("photo")), bmWrite);
   Image1.Picture.Graphic.SaveToStream(bs);
   bs.Free;
 end

На создании потока вываливается с ошибкой: "... raised exeption class EInvalidCast with massage "Invalid class typecast""
В чем проблема?


 
Alarm ©   (2006-03-23 13:42) [1]

Позволь узнать куда ты собираешься записать картинку?. В какую запись в базе? Не вижу запроса,  не вижу Edit (Append), ну и соответственно Post???
Возможно это куда-нибудь продвинет тебя


 
DmitryNekl   (2006-03-23 13:46) [2]

Нет, конечно, Insert и Post есть. Я привел только те строчки, которые имеют отношение к делу.
Суть такая: на форму перетаскивается графический файл. Он загружается в Image1. А затем я вставляю новую запись с помощью вышеприведенного когда в поле "photo".
Вот полный код этой процедуры, со всеми деталями:

procedure TForm1.WMDropFiles(var Msg: TMessage);
var Filename: array[0 .. 256] of Char;
   Count: integer;
   JPG: TJPEGImage;
   bs: TBlobStream;
begin
 Count := DragQueryFile(msg.WParam, $FFFFFFFF, nil, 0);
 DragQueryFile( THandle(Msg.WParam), 0, Filename,SizeOf(Filename));

 photos.Insert;

 Image1.Picture.LoadFromFile(LowerCase(StrPas(FileName)));
 if Image1.Picture.Graphic is TJPegImage then
 begin
   bs:=TBlobStream.Create(TBlobField(photos.FieldByName("photo")), bmWrite);
   (Image1.Picture.Graphic as TJpegImage).SaveToStream(bs);
   bs.Free;
 end
 else
 if Image1.Picture.Graphic is TBitmap then
 begin
   Jpg:=TJPegImage.Create;
   Jpg.Assign(Image1.Picture.Graphic);
   Jpg.JPEGNeeded;
   bs:=TBlobStream.Create(photos.FieldByName("photo") as TBlobField, bmWrite);
   Jpg.SaveToStream(bs);
   bs.Free;
   Jpg.Free;
 end;

 Photos.Post;

 DragFinish(THandle(Msg.WParam));
end;


 
Alarm ©   (2006-03-23 13:59) [3]

photos.Insert;
Думается, что при работе с Access этот код сработал бы. Ну, а я бы еще посоветовал поэкспериментировать с Append. Не совсем разобрался куда пишем (инсёртим):(


 
Alarm ©   (2006-03-23 14:16) [4]

Постараюсь подытожить, пока в коде не увижу слово "запрос" или SQL, думаю никаких советов не последует.
Сорри:(


 
Ega23 ©   (2006-03-23 14:23) [5]

А photos.FieldByName("photo") - точно BLOB?
Потому как, по-идее, вроде всё верно.
Не мешало-бы добавить try-except конструкции, да и вот это

if Image1.Picture.Graphic is TBitmap then
begin
  Jpg:=TJPegImage.Create;
  Jpg.Assign(Image1.Picture.Graphic);


мне не совсем ясно: если BMP> то зачем JPEG? :о)

А в целом должно работать.

2 Alarm ©   (23.03.06 14:16) [4]

> Постараюсь подытожить, пока в коде не увижу слово "запрос"
> или SQL, думаю никаких советов не последует.
> Сорри:(


Ты неправильно думаешь. И подытоживаешь тоже.


 
vovnuke ©   (2006-03-23 14:30) [6]

TClientDataSet не является наследником TBDEDataSet, поэтому в конструкторе TBlobStream происходит ошибка приведения типов


 
DmitryNekl   (2006-03-23 20:15) [7]

2 Ega23:

photos.FieldByName("photo") - точно BLOB :) (см. первый пост вопроса - там оно создается именно как Blob).

Проблема именно в том, как jpeg засунуть в базу, bmp я умею (правда, другими методами). Вообще говоря, этот пример я нашел в инете и переработал под свою ситуацию.

Похоже, vovnuke прав. Однако это не объясняет, что делать :)

Какие необходимо внести изменения, чтобы все работало в TClientDataSet? Или поставим вопрос иначе: каким образом в TClientDataSet можно засунуть jpeg-картинку?


 
Desdechado ©   (2006-03-23 20:47) [8]

TDataSet.CreateBlobStream попробуй


 
vovnuke ©   (2006-03-24 09:17) [9]

точнее ClientDataSet.CreateBlobStream()


 
DmitryNekl   (2006-03-24 10:46) [10]

Попробовал... Сообщение об ошибке поменялось :)

var bs: TStream;
begin
 ...
 photos.Insert;
 if Image1.Picture.Graphic is TJPegImage then
 begin
   bs:=photos.CreateBlobStream(photos.FieldByName("photo"), bmWrite);
   (Image1.Picture.Graphic as TJpegImage).SaveToStream(bs);
   bs.Free;
 end
 photos.Post;
 ...
end

теперь приводит к EInvalidGraphic with message "Bitmap image is not valid" :(


 
Desdechado ©   (2006-03-24 11:41) [11]

значит, поле photos.FieldByName("photo") - не блоб, а график
выставь ему нужный тип


 
DmitryNekl   (2006-03-24 11:59) [12]

Попробовал - не идет. Код:

if not FileExists(photos.FileName) then
begin
  photos.FieldDefs.Clear;
  photos.FieldDefs.Add("id", ftInteger);
  photos.FieldDefs.Add("photo", ftGraphic);
  photos.CreateDataSet;
end;
photos.Open;
photos.SaveToFile();


Посмотрел справку, ftGraphic - Bitmap field. Попробовал при сохранении типа поля ftGraphic загрузить BMP:

 if Image1.Picture.Graphic is TBitmap then
 begin
   bs:=photos.CreateBlobStream(photos.FieldByName("photo"), bmWrite);
  (Image1.Picture.Graphic as TBitmap).SaveToStream(bs);
   bs.Free;
 end;


Все работает.

Соответственно, вопрос остается открытым: как засунуть в ClientDataSet картинку jpeg?


 
Desdechado ©   (2006-03-24 13:01) [13]

для тех, кто в танке: использовать блоб, а не график
т.к. график только для BMP


 
Ega23 ©   (2006-03-24 13:35) [14]


var
ms:TMemoryStream;
jpg:TJPEGImage;
begin
 jpg:=TJPEGImage.Create;
 ms:=TMemoryStream.Create;
 try
   jpg.Assign(Image1.Picture);
   jpg.SaveToStream(ms);
   CDS.Edit; // (или Insert)
   TBLOBField(CDS.FieldByName("photo")).LoadFromStream(ms);
   CDS.Post;
 finally
   ms.Free;
   jpg.Free;
 end;
end;


 
Ega23 ©   (2006-03-24 13:36) [15]

Image1.Picture.Graphic  вроде.

Не проверял, прям тут код писал.
Естественно, надо убедиться, что в Image1 именно JPEG


 
DmitryNekl   (2006-03-24 14:01) [16]

А один черт:  EInvalidGraphic with message "Bitmap image is not valid"

Поле - blob, не graphic

   
var
 JPG: TJPEGImage;
 ms: TMemoryStream;
begin
 photos.Insert;
 Image1.Picture.LoadFromFile(LowerCase(StrPas(FileName)));
 if Image1.Picture.Graphic is TJPegImage then
 begin
   jpg:=TJPEGImage.Create;
   ms:=TMemoryStream.Create;
   try
     jpg.Assign(Image1.Picture.Graphic); // пробовал и просто Image1.Picture
     jpg.SaveToStream(ms);
     TBLOBField(photos.FieldByName("photo")).LoadFromStream(ms);
   finally
     ms.Free;
     jpg.Free;
   end;
 end;
 photos.Post;
end;


 
Ega23 ©   (2006-03-24 14:18) [17]

А это JPEG?


 
DmitryNekl   (2006-03-24 15:04) [18]

Да, конечно. Самый что ни на есть настоящий jpeg :)


 
Desdechado ©   (2006-03-24 17:46) [19]

> EInvalidGraphic with message "Bitmap image is not valid"
> Поле - blob, не graphic
Судя по ошибке, не верю. В датасете-таки все равно график


 
Ega23 ©   (2006-03-24 18:01) [20]

Сотри файл .cds и создай его заного. Т.к. ошибок я не вижу. Ну разве что не пользовался FieldDefs.Add("id", ftInteger), а использовал With FieldDefs.AddFieldDef do, но судя по справке это одно и то же.


 
DmitryNekl   (2006-03-24 21:16) [21]

Я за время экспериментов не один раз уж все стирал... Еще раз попробовал. Ну не работает! Факт - вещь упрямая :)

Еще раз.

Создание:

 photos.FileName:=ExtractFilePath(Application.ExeName)+"photos.cds";
 if not FileExists(photos.FileName) then
 begin
   photos.FieldDefs.Clear;
   photos.FieldDefs.Add("id", ftInteger);
   photos.FieldDefs.Add("photo", ftBlob);
   photos.CreateDataSet;
 end;
 photos.Open;
 photos.SaveToFile();


Поле id - это связь master-detail, к сути вопроса отношения не имеет.

Засовывание картинки (с bmp работает, с jpg - нет):

var  
   JPG: TJPEGImage;
   bs: TStream;
   ms: TMemoryStream;
begin
 Image1.Picture.LoadFromFile(...);
 Photos.Insert;
 if Image1.Picture.Graphic is TJPegImage then
 begin
   jpg:=TJPEGImage.Create;
   ms:=TMemoryStream.Create;
   try
     jpg.Assign(Image1.Picture);  // пробовал и Image1.Picture.Graphic
     jpg.SaveToStream(ms);
     TBLOBField(photos.FieldByName("photo")).LoadFromStream(ms);
   finally
     ms.Free;
     jpg.Free;
   end;
 end
 else
 if Image1.Picture.Graphic is TBitmap then
 begin
   bs:=photos.CreateBlobStream(photos.FieldByName("photo"), bmWrite);
   (Image1.Picture.Graphic as TBitmap).SaveToStream(bs);
   bs.Free;
 end;
 Photos.Post;
end;


Ошибка прежняя - EInvalidGraphic with message "Bitmap image is not valid".

Может быть, есть еще версии?


 
sniknik ©   (2006-03-24 23:38) [22]

{pas}
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, DB, Grids, DBGrids, DBClient, jpeg, ExtCtrls;

type
 TForm1 = class(TForm)
   ClientDataSet1: TClientDataSet;
   DataSource1: TDataSource;
   DBGrid1: TDBGrid;
   ClientDataSet1ID: TIntegerField;
   Button1: TButton;
   ClientDataSet1Name: TStringField;
   ClientDataSet1Blb: TBlobField;
   ClientDataSet1Grph: TGraphicField;
   Image1: TImage;
   Button2: TButton;
   Button3: TButton;
   Button4: TButton;
   Image2: TImage;
   procedure FormCreate(Sender: TObject);
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   procedure Button3Click(Sender: TObject);
   procedure Button4Click(Sender: TObject);
 private
 public
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 with ClientDataSet1 do begin
   CreateDataSet;
   Append;
   FieldByName("ID").AsInteger:= 1;
   FieldByName("Name").AsString:= "Test";
   Post;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var ms: TMemoryStream;
begin
 ms:= TMemoryStream.Create;
 try
   with ClientDataSet1 do begin
     Edit;
     Image1.Picture.Graphic.SaveToStream(ms);
     ms.Position:= 0;
     ClientDataSet1Blb.LoadFromStream(ms);
     Post;
   end;
 finally
   ms.Free;
 end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 ms: TMemoryStream;
begin
 ms:= TMemoryStream.Create;
 try
   if not ClientDataSet1Blb.IsNull then begin
     ClientDataSet1Blb.SaveToStream(ms);
     ms.Position:= 0;
     with Image2.Picture do begin
       Graphic:= TJPEGImage.Create;
       Graphic.LoadFromStream(ms);
     end;
   end;
 finally
   ms.Free;
 end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 ClientDataSet1.SaveToFile("D:\TestClientDS.CDS");
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
 ClientDataSet1.LoadFromFile("D:\TestClientDS.CDS");
end;

end.

{dfm}
object Form1: TForm1
 Left = 176
 Top = 72
 Width = 371
 Height = 425
 Caption = "Form1"
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = "MS Sans Serif"
 Font.Style = []
 OldCreateOrder = False
 OnCreate = FormCreate
 PixelsPerInch = 96
 TextHeight = 13
 object Image1: TImage
   Left = 5
   Top = 5
   Width = 124
   Height = 92
   Picture.Data = {сюда надо вставить картинку jpg иначен ничего не выйдет...
                         т.е. удалить этот текст и пункт Picture.Data и загрузить  
                          свою когда будет в виде формы (у меня уж больно большая)
}
   Stretch = True
 end
 object Image2: TImage
   Left = 229
   Top = 5
   Width = 124
   Height = 92
   Stretch = True
 end
 object DBGrid1: TDBGrid
   Left = 8
   Top = 104
   Width = 345
   Height = 249
   DataSource = DataSource1
   TabOrder = 0
   TitleFont.Charset = DEFAULT_CHARSET
   TitleFont.Color = clWindowText
   TitleFont.Height = -11
   TitleFont.Name = "MS Sans Serif"
   TitleFont.Style = []
 end
 object Button1: TButton
   Left = 8
   Top = 363
   Width = 75
   Height = 25
   Caption = "In"
   TabOrder = 1
   OnClick = Button1Click
 end
 object Button2: TButton
   Left = 96
   Top = 363
   Width = 75
   Height = 25
   Caption = "Out"
   TabOrder = 2
   OnClick = Button2Click
 end
 object Button3: TButton
   Left = 184
   Top = 363
   Width = 75
   Height = 25
   Caption = "Save"
   TabOrder = 3
   OnClick = Button3Click
 end
 object Button4: TButton
   Left = 272
   Top = 363
   Width = 75
   Height = 25
   Caption = "Load"
   TabOrder = 4
   OnClick = Button4Click
 end
 object ClientDataSet1: TClientDataSet
   Aggregates = <>
   Params = <>
   Left = 24
   Top = 128
   object ClientDataSet1ID: TIntegerField
     FieldName = "ID"
   end
   object ClientDataSet1Name: TStringField
     FieldName = "Name"
   end
   object ClientDataSet1Blb: TBlobField
     FieldName = "Blb"
   end
   object ClientDataSet1Grph: TGraphicField
     FieldName = "Grph"
     BlobType = ftGraphic
   end
 end
 object DataSource1: TDataSource
   DataSet = ClientDataSet1
   Left = 64
   Top = 128
 end
end


сдесь с blob, но есть и поле "график" для пробы с ним (разници нет)


 
DmitryNekl   (2006-03-25 00:13) [23]

Да, в данном примере все работает - я проверил.
В чем разница с моим примером?
Здесь поля определяются через редактор полей, а у меня - в run-time. Может быть, какие-то еще действия необходимы, кроме
 photos.FieldDefs.Clear;
 photos.FieldDefs.Add("id", ftInteger);
 photos.FieldDefs.Add("photo", ftGraphic);
 photos.CreateDataSet;
?
Больше я не вижу причин, почему не работает. Привел последний пример к своему виду. Вся разница - в строчках:
ClientDataSet1Blb.LoadFromStream(ms); здесь и
(photos.FieldByName("photo") as TBlobField).LoadFromStream(ms); - у меня.

И вот на этой строчке возникает непонятно откуда ошибка.


 
sniknik ©   (2006-03-25 00:51) [24]

не сдесь
замени у меня
//ClientDataSet1Blb.LoadFromStream(ms);
на
(FieldByName("Blb") as TBlobField).LoadFromStream(ms);
работать не перестанет.

и редактор полей не причем, одно и тоже с "динамикой". (просто удобнее в редакторе...)


 
DmitryNekl   (2006-03-25 12:11) [25]

Все, разобрался. Всем спасибо!
Если интересно: на это поле был подвешен DBImage, он и генерил ошибку.


 
sniknik ©   (2006-03-25 12:24) [26]

> на это поле был подвешен DBImage
но весде в примерах ты оперировал Image-м (показал бы реальный код, я бы тебе сразу сказал причину. это давно всем(/вернее многим ;) известно, что DBImage только с bmp работает)


 
DmitryNekl   (2006-03-25 13:23) [27]

Да... я его подвесил и забыл о нем :)

Я, на самом деле, и показывал реальный код, нигде в ходе DBImage и не фигурировал. Просто был настроен на отображение поля photos.photo, и при попытке загрузки в это поле jpg-изображения именно на вышеприведенных строчках выдавал исключение.

Еще раз спасибо!



Страницы: 1 вся ветка

Текущий архив: 2006.04.09;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.033 c
2-1143275526
Alex7
2006-03-25 11:32
2006.04.09
????????????


2-1143105524
SergeyG
2006-03-23 12:18
2006.04.09
Есть файл байтов (file of byte). Как сделать, чтобы массив данных


15-1142888315
xlsn
2006-03-20 23:58
2006.04.09
WebMoney


15-1142840270
Knight
2006-03-20 10:37
2006.04.09
Как перенести настроенный диалап из одного XP в другой?


2-1143463840
sofi
2006-03-27 16:50
2006.04.09
Разрешение экрана