Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1143047641
Adios
2006-03-22 20:14
2006.04.09
вопрос насчёт других приложений


15-1142280363
Eraser
2006-03-13 23:06
2006.04.09
Использовать impersonation с пом. SSPI или named pipes


2-1143012046
Ньюб2
2006-03-22 10:20
2006.04.09
предотвратить отключение монитора


15-1142933816
Fin
2006-03-21 12:36
2006.04.09
Обновление антивирусных баз у Symantec?


15-1142344093
Mozgan
2006-03-14 16:48
2006.04.09
Требуем конкурс для чайников!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский