Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Не могу понять, в чем ошибка. [D7, ClientDataSet]


Страницы:   1 2

DmitryNekl ©   (2006-03-23 12:26:00) 

Буду признателен за помощь.
Хочу сохранить картинку 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'"
В чем проблема?


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

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

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

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


sniknik   (2006-03-25 12:24:00) [2]

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


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

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


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

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

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


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

Да, в данном примере все работает - я проверил.
В чем разница с моим примером?
Здесь поля определяются через редактор полей, а у меня - в 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-24 23:38:00) [6]

{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-24 21:16:00) [7]

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

Еще раз.

Создание:

 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".

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


Ega23   (2006-03-24 18:01:00) [8]

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


Desdechado   (2006-03-24 17:46:00) [9]

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


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

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


Ega23   (2006-03-24 14:18:00) [11]

А это JPEG?


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

А один черт:  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 13:36:00) [13]

Image1.Picture.Graphic  вроде.

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


Ega23   (2006-03-24 13:35:00) [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;


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

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


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

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

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 11:41:00) [17]

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


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

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

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" :(


vovnuke   (2006-03-24 09:17:00) [19]

точнее ClientDataSet.CreateBlobStream()


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

TDataSet.CreateBlobStream попробуй


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо