Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Искажение картинок при записи в БД (MySQL)


Автор: AnacRon 18.3.2010, 12:11
Доброго времени суток!
Столкнулся с проблемой записи изображения в БД MySQL.
Имеем:
Главную форму приложения с PageControl. 1 - TfmMain. - AutoCreate
Форму с компонентами БД (пробовал стандартные dbExpress и Zeos) 2 - TfmSQL. - AutoCreate
Форму со списком записей 3 - TfmStore. - no AutoCreate
Форму редактирования записи БД 4 - TfmEdit. - no AutoCreate (Ввиду ряда причин не используются стандартные компоненты DataControl)

В процессе работы создается динамически 3 - TfmStore и кладется на закладку PageControl главной формы. 
Код

procedure TfmMain.storExecute(Sender: TObject);
var
  form: TForm;
  t: TTabSheet;
begin
  t := TTabSheet.Create(pcMain);
  with t do
  begin
    PageControl := pcMain;
    pcMain.ActivePageIndex := pcMain.PageCount - 1;

    form := TfmStore.Create(Self);
    Caption := form.Caption;
    form.Parent := t;
    form.BoundsRect := t.ClientRect;
    form.Align := alClient;
    form.Show;

    Visible := True;
  end;
end;

Если пользователь желает просмотреть/изменить запись БД, то создается динамически 4 - TfmEdit и вызывается через ShowModal.
Код

procedure TfmStore.EditExecute(Sender: TObject);
begin
  try
    with TfmEdit.Create(Self) do
    begin
      if ShowModal = mrOk then
      begin
        // Ok
      end;
      Free;
    end;
  except
    //except
  end;
end;


на форме 4 - TfmEdit имеем TImage для отображения картинки из БД
для записи картинки использую код:
Код

procedure TfmEdit.AddExecute(Sender: TObject);
var
  st: TStream;
begin
  st := TMemoryStream.Create;
  Image.Picture.Bitmap.SaveToStream(st);
  st.Position := 0;
  with SQLQuery do
  begin
    SQL.Clear;
    SQL.Add('UPDATE store SET img1=:im1 WHERE plu='+Edit1.Text+' LIMIT 1');
    Params.ParseSQL(SQL.Text, true);
    with Params.CreateParam(ftBlob, 'im1', ptInput) do Clear;
    Params.ParamByName('im1').LoadFromStream(st, ftBlob);
    ExecSQL;
    Params.ParamByName('im1').Free;
  end;
  st.Free;
end;

Код для чтения:
Код

procedure TfmEdit.ViewExecute(Sender: TObject);
var
  st: TStream;
begin
  st := TMemoryStream.Create;
  with SQLQuery do
  begin
    SQL.Clear;
    SQL.Add('SELECT img1 FROM store WHERE plu='+Edit1.Text);
    Open;
    st := CreateBlobStream(FieldByName('img1'), bmRead);
    Image.Picture.Bitmap.LoadFromStream(st);
    Close;
  end;
  st.Free;
end;

Ошибок при работе не возникает, но в БД картинка хранится искаженной :(
вот что получается
До записи в БД user posted image, после записи в БДuser posted image

В чем геморой? До меня ни как не дойдет...

З.Ы
если использовать тот же код для чтения и записи картинок из/в БД на главной форме, без динамически вызванных форм 3 и 4, то картинки не искажаются
З.З.Ы.
MySQL-5.0 (win32, linux), CodeGear 2007, winXPpro sp3

Автор: pseud 19.3.2010, 10:25
картинка бывает только *.bmp?

у себя нарыл такой код, вставка:
Код

procedure TForm1.Button2Click(Sender: TObject);
var
  strm: TMemoryStream;
begin
  with TQuery.Create(Self) do
  try
    DatabaseName := FAppPath;
    SQL.Add('INSERT INTO graphic_storage (content) values (:param1)');
    strm := TMemoryStream.Create;
    try
      Image1.Picture.Graphic.SaveToStream(strm);
      Params.ParamByName('param1').LoadFromStream(strm, ftGraphic);
    finally
      strm.Free;
    end;
    ExecSQL;
  finally
    Free;
  end;
end;

чтение:
Код

procedure LoadPictureFormBLOB(aField:TField;aPicture:TPicture);
var
  stBLOB: tStream;
begin
  stBLOB := aField.DataSet.CreateBlobStream(aField,bmRead);
  try
    aPicture.Graphic := TJPEGImage.Create;
    stBLOB.Seek(0, soFromBeginning);
    aPicture.Graphic.LoadFromStream(stBLOB);
  finally
    stBLOB.Free;
  end;
end;

procedure TForm1.GetContentClick(Sender: TObject);
begin
  with TQuery.Create(Self) do
  try
    DatabaseName := FAppPath;
    SQL.Add('SELECT * FROM graphic_storage WHERE id = ' + Edit1.Text);
    Active := True;
    LoadPictureFormBLOB(FieldByName('content'), Image2.Picture);
  finally
    Free;
  end;
end;

Автор: AnacRon 20.3.2010, 14:26
не помог этот код (((
искажения так же остались

Автор: AnacRon 3.4.2010, 17:01
нашел решение этого момента. 
т.к. первоначально база забивалась разными людьми и задолго до меня, все данные хранились в кодировке cp1251 для удобства работы и перспектив на будущее на событие onAfterConnect вешался запрос:
Код

SET character_set_client=utf8, character_set_connection=cp1251, character_set_results=utf8;
 после отключения чего и стала прога писать картинки в БД без искажеий и ошибок

всем спасибо, все свободны  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)