Форум: "Начинающим";
Текущий архив: 2006.04.09;
Скачать: [xml.tar.bz2];
ВнизНе могу понять, в чем ошибка. Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.381 c