![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Не могу понять, в чем ошибка. [D7, ClientDataSet]
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 попробуй