Page 1 of 1

Pre Scale Image During Insert ?

Posted: Thu Dec 30, 2010 7:04 am
by andyhill
Hi, Please advise how to pre scale image during insert ?

pic:= TPicture.Create;
try
pic.LoadFromFile(OpenDialog1.FileName);

bm:= TBitmap.Create;
bm.Height:= 100; // fudge value for testing
bm.Width:= 100; // fudge value for testing

ARect:= Rect(0, 0, bm.Height, bm.Width);
bm.Canvas.StrechDraw(ARect, pic.Bitmap); // FAILS HERE ?
pic.Bitmap.Assign(bm);
bm.Free;

gr:= RV_CreateGraphics(TGraphicClass(pic.Graphic.ClassType));
gr.Assign(pic.Graphic);
finally
pic.Free;
end;

Andy

Posted: Thu Dec 30, 2010 1:08 pm
by Sergey Tkachenko
When you call pic.Bitmap, if pic did not contain bitmap, the existing image in pic is discarded, and a new blank TBitmap is created.

Change all pic.Bitmap to pic.Graphic.

There is one more possible problem: assignment of TBitmap to some graphic types may be not implemented (exception occurs).
In this case, we can convert it to bitmap.

Code: Select all

pic:= TPicture.Create; 
try 
  pic.LoadFromFile(OpenDialog1.FileName); 

  bm:= TBitmap.Create; 
  bm.Height:= 100; // fudge value for testing 
  bm.Width:= 100; // fudge value for testing 

  ARect:= Rect(0, 0, bm.Height, bm.Width); 
  bm.Canvas.StrechDraw(ARect, pic.Graphic); 

  gr:= RV_CreateGraphics(TGraphicClass(pic.Graphic.ClassType)); 
  try
    gr.Assign(bm); 
    bm.Free;
  except
    gr := bm; 
  end;
finally 
  pic.Free; 
end; 
Now you can insert gr.

Another solution: insert the original image, but display it scaled using trichview item properties.

Posted: Thu Dec 30, 2010 8:34 pm
by andyhill
Thanks Sergey,

1) My StrechDraw method will not compile (which unit must I put in the uses clause) ?

2) Can you show me code "display it scaled using trichview item properties" on insert where we constrain the size to the current table cell size ?

Thanks Again

Posted: Thu Dec 30, 2010 8:51 pm
by Sergey Tkachenko
1) 't' is missed, StretchDraw
2) I'll post an example later

Posted: Thu Dec 30, 2010 9:24 pm
by andyhill
(1) Thanks, I feel rather silly missing that one

(2) I look forward to your example

Posted: Sun Jan 02, 2011 1:59 pm
by Sergey Tkachenko
When the caret is in a table cell, the editor for this cell is available as RichViewEdit1.TopLevelEditor. You can get its width and subtract left and right margins.

Image is scaled by assigning rvepImageHeight and rvepImageWidth properties.

To make this assignment as one operation (that the user can undo in one step), a sequence of call BeginUndoGroup, SetUndoGroupMode(True)...SetUndoGroupMode(False) is used.

To prevent twitching while inserting and resizing, BeginUpdate...EndUpdate is used.

Code: Select all

var bmp: TBitmap;
    rve: TCustomRichViewEdit;
    w: Integer;
begin
  rve := RichViewEdit1.TopLevelEditor;
  bmp := TBitmap.Create;
  bmp.LoadFromFile('d:\1.bmp');
  if RichViewEdit1=rve then begin
    // we are not in cell
    rve.InsertPicture('', bmp, rvvaBaseline);
    exit;
  end;
  w := rve.TopLevelEditor.Width-
    (rve.TopLevelEditor.LeftMargin+rve.TopLevelEditor.RightMargin);
  rve.BeginUpdate;
  try
    rve.BeginUndoGroup(rvutInsert);
    rve.SetUndoGroupMode(True);
    if rve.InsertPicture('', bmp, rvvaBaseline) then begin
      rve.SetCurrentItemExtraIntProperty(rvepImageHeight, w, True);
      rve.SetCurrentItemExtraIntProperty(rvepImageWidth, w, True);
    end;
  finally
    rve.SetUndoGroupMode(False);
    rve.EndUpdate;
    rve.Invalidate;
  end;
end;

Posted: Sun Jan 02, 2011 9:32 pm
by andyhill
Thanks Sergey for your support, truly appreciated - however I have some issues (please look for ***):-

Code: Select all

procedure TfRichView.Print1Click(Sender: TObject);
var
  PrintIt: Boolean;
  ClientName, s: String;
  table: TRVTableItemInfo;
  i, w: Integer;
  ItemInfo: TCustomRVItemInfo;
  //
  bm: TBitmap;
  RVData: TCustomRVFormattedData;
  Row, Column: Integer;
begin
  PrintIt:= psd.Execute;
  if PrintIt then begin
    // Build Client Name
    ClientName:= '';
    case fMain.Table0.FieldByName('Gender').AsInteger of
      1: ClientName:= 'Mr ';
      2: ClientName:= 'Mrs ';
      3: ClientName:= 'Ms ';
      4: ClientName:= 'Miss ';
    end;
    ClientName:= ClientName+fMain.Table0.FieldByName('FirstName').AsString+' '+fMain.Table0.FieldByName('LastName').AsString;
    // Build Some Style Elements
    rvs2.TextStyles.Clear;
    rvs2.TextStyles.AddFont('Times New Roman', 14, clBlack, clWhite, [fsBold]);
    rvs2.TextStyles.AddFont('Times New Roman', 12, clBlack, clWhite, []);
    rvs2.ParaStyles.Clear;
    rvs2.ParaStyles.Add;
    rvs2.ParaStyles[0].Alignment:= rvaCenter;
    rvs2.ParaStyles.Add;
    rvs2.ParaStyles[1].Alignment:= rvaLeft;
    // Assign rvs2 to Hidden rve2
    rve2.Style:= rvs2;
    // Build hidden rev2 contents
    rve2.Clear;
    rve2.AddNL('Business Name', 0, 0);
    rve2.AddNL('Business Address', 0, 0);
    rve2.AddNL('', 0, 0);
    rve2.AddNL('CLIENT NOTES', 1, 0);
    rve2.AddNL(ClientName, 1, 0);
    rve2.AddNL('', 0, 1);
    rve2.FormatTail;
    // Copy our visual editor rve contents (append) to our hidden rve2 editor
    RVCopy(rve, rve2);
    rve2.FormatTail;
    // Add Blank Line between above and table below
    rve2.AddNL('', 0, 1);
    rve2.FormatTail;
    // Build Table 
    table:= TRVTableItemInfo.CreateEx(4, 2, rve2.RVData);
    table.BorderStyle:= rvtbRaisedColor;
    table.CellBorderStyle:= rvtbLoweredColor;
    table.BorderWidth:= 1;
    table.CellBorderWidth:= 1;
    table.CellPadding:= 5;
    table.CellVSpacing:= 1;
    table.CellHSpacing:= 1;
    table.BorderVSpacing:= 1;
    table.BorderHSpacing:= 1;
    // Add Table to rve2
    rve2.AddItem('MyTempTable', table);
    rve2.FormatTail;
    ///////////////////////////////////////////////////////////////////////////
    // Locate table in hidden rve2 and edit cells
    for i:= 0 to rve2.ItemCount -1 do begin
      if (rve2.GetItemStyle(i) = rvsTable) and (rve2.GetItemText(i) = 'MyTempTable') then begin
        table:= TRVTableItemInfo(rve2.GetItem(i));
        // First Row Cell Edit
        Row:= 0;
        Column:= 0;
        table.EditCell(Row, Column);
        // Move the caret to the beginning of this cell
        RVData:= TCustomRVFormattedData(table.Cells[Row, Column].GetRVData);
        RVData.SetSelectionBounds(0, RVData.GetOffsBeforeItem(0), 0, RVData.GetOffsBeforeItem(0));
        // Add Bitmap to cell
        bm:= TBitmap.Create;
        bm.LoadFromFile('D:\D2011\Editor\image.bmp');
        w:= rve2.TopLevelEditor.Width - (rve2.TopLevelEditor.LeftMargin + rve2.TopLevelEditor.RightMargin); 
        // *** w does not reflect true rendered paper page size (only hidden rve2 VCL size), will this be adjusted relatively on the fly ??? ***
        try
          rve2.BeginUpdate;
          rve2.BeginUndoGroup(rvutInsert);
          rve2.SetUndoGroupMode(True);
          // *** Fails To Insert bm into cell ??? ***
          if rve2.InsertPicture('', bm, rvvaAbsMiddle) then begin
            rve2.SetCurrentItemExtraIntProperty(rvepImageHeight, w, True);
            rve2.SetCurrentItemExtraIntProperty(rvepImageWidth, w, True);
            // *** This AddNL data does not paint in focused cell ??? ***
            rve2.AddNL('Image', 1, 0);
          end;
        finally
          bm.Free;
          rve2.SetUndoGroupMode(False);
          rve2.EndUpdate;
          rve2.Invalidate;
        end;
        ////////////////////////////////////////////////////////////////////////
        // ReFetch Table (just in case it needs refreshing)
        table:= TRVTableItemInfo(rve2.GetItem(i));
        // Second Row Cell Edit
        Row:= 1;
        Column:= 0;
        table.EditCell(Row, Column);
        // Move the caret to the beginning of this cell
        RVData:= TCustomRVFormattedData(table.Cells[Row, Column].GetRVData);
        RVData.SetSelectionBounds(0, RVData.GetOffsBeforeItem(0), 0, RVData.GetOffsBeforeItem(0));
        // Add RVF data to cell
        rve2.BeginUpdate;
        try
          rve2.BeginUndoGroup(rvutInsert);
          rve2.SetUndoGroupMode(True);
          rve2.TopLevelEditor.InsertRVFFromFileEd('D:\D2011\Editor\test.rvf');
        finally
          rve2.SetUndoGroupMode(False);
          rve2.EndUpdate;
          rve2.Invalidate;
        end;
        //
        Break;
      end;
    end; // for i
    rve2.Format;
    ///////////////////////////////////////////////////////////////////////////
    // *** Attempt to resolve FormatPages error below ***
    //RVPrint1.AssignSource(rve2); 
    rve2.SaveRVF('D:\D2011\Editor\test.rvf', False);
    RVPrint1.rv.LoadRVF('D:\D2011\Editor\test.rvf');
    //
    RVPrint1.LeftMarginMM:= 10;
    RVPrint1.RightMarginMM:= 10;
    RVPrint1.TopMarginMM:= 10;
    RVPrint1.BottomMarginMM:= 10;
    // *** ACCESS VIOLATION ON FormatPages ***
    RVPrint1.FormatPages(rvdoALL);
    //
    if RVPrint1.PagesCount > 0 then begin
      //RVPrint1.Print('test', 1, False);
      fPrintPreview.rvpp.RVPrint:= RVPrint1;
      fPrintPreview.Button1Click(nil);
      fPrintPreview.ShowModal;
    end; // PagesCount
    //
  end; // PrintIt
end;
Note: Even if rve2 is hidden (visible = False) it paints on form after it is worked with (I now have it placed behind rve to keep hidden) ???

Posted: Mon Jan 03, 2011 9:06 am
by Sergey Tkachenko
1. Do not free the image after inserting it in the editor (remove the line bm.Free;)

2. Do not load document in RVPrint.rv. RVPrint.rv is a special TRichView that cannot contain items, it can only use items from another RichView (assigned by AssignSource)

3. What size exactly must the picture have?

Posted: Mon Jan 03, 2011 7:33 pm
by andyhill
So if I need to add 30 images I need to have 30 Bitmap Objects ??? If this is so it seems cumbersome ???

I need the Table (100% of page) with 2 cells which would make the desired cell (50% of page) so Bitmap size should be scaled to cell width taking into account the aspect ratio (we have already chosen printer and orientation at this point).

I still get access violation after running this print/preview code on closedown ?

Posted: Tue Jan 04, 2011 1:11 am
by andyhill
Sergey, I have used my real code (not mockup) and ask for help with:-

1) Scaling images 50% of paper/orientation selection (rve2 image table has 2 cells) with aspect ratio preserved

2) Inserting RVF streams (from Unicode DB) into rve2 notes table

Code: Select all

procedure TfRichView.Print1Click(Sender: TObject);
var
  PrintIt, Filtered: Boolean;
  ClientName, s: String;
  table, table2: TRVTableItemInfo;
  i, j, k, l, r, c, w: Integer;
  ItemInfo: TCustomRVItemInfo;
  //
  jpeg: TJPEGImage;
  bm: TBitmap;
  //
  RVData: TCustomRVFormattedData;
  CRLF, CaptionInfo: String;
  //
  ClientImagesCount, ModCount, RowCount, CellCount, ClassificationNotesCount, CurTextStyleNo, CurParStyleNo, ID: Integer;
  bs, bsF: TEDBBlobStream;
  mss: TStringStream;
  ms: TMemoryStream;
begin
  //
  ClassificationNotesCount:= 0;
  ClientImagesCount:= 0;
  RowCount:= 0;
  CellCount:= 0;
  if rve.DataSource = fMain.dsTable0 then begin
    ClientImagesCount:= fMain.ImageEnMView2.MultiSelectedImagesCount;
    if fClassificationNotes.ShowModal <> mrOK then Exit;
    for i:= 0 to fClassificationNotes.clClassifications.Items.Count-1 do begin
      if fClassificationNotes.clClassifications.Items[i].Checked = True then begin
        Inc(ClassificationNotesCount);
      end;
    end;
    ModCount:= ClientImagesCount mod 2;
    RowCount:= ClientImagesCount div 2;
    if ModCount > 0 then Inc(RowCount);
    CellCount:= 2;
  end;
  //
  CRLF:= #10+#13;
  PrintIt:= psd.Execute;
  if PrintIt then begin
    //
    ClientName:= '';
    case fMain.Table0.FieldByName('Gender').AsInteger of
      1: ClientName:= 'Mr ';
      2: ClientName:= 'Mrs ';
      3: ClientName:= 'Ms ';
      4: ClientName:= 'Miss ';
    end;
    ClientName:= ClientName+fMain.Table0.FieldByName('FirstName').AsString+' '+fMain.Table0.FieldByName('LastName').AsString;
    ////////////////////////////////////////////////////////////////////////////
    //rvs2.ResetTextStyles; // Add Defaults
    rvs2.TextStyles.Clear;
    rvs2.TextStyles.AddFont('Times New Roman', 14, clBlack, clWhite, [fsBold]);
    rvs2.TextStyles.AddFont('Times New Roman', 12, clBlack, clWhite, []);
    //rvs2.ResetParaStyles; // Add Defaults
    rvs2.ParaStyles.Clear;
    rvs2.ParaStyles.Add;
    rvs2.ParaStyles[0].Alignment:= rvaCenter;
    rvs2.ParaStyles.Add;
    rvs2.ParaStyles[1].Alignment:= rvaLeft;
    //
    rve2.Style:= rvs2;
    ////////////////////////////////////////////////////////////////////////////
    rve2.Clear;
    rve2.AddNL('My Business Name', 0, 0);
    rve2.AddNL('My Business Address', 0, 0);
    rve2.AddNL('', 0, 0);
    rve2.AddNL('CLIENT NOTES', 1, 0);
    rve2.AddNL(ClientName, 1, 0);
    rve2.AddNL('', 0, 1);
    rve2.FormatTail;
    ////////////////////////////////////////////////////////////////////////////
    // Append Original RVF to rve2
    RVCopy(rve, rve2);
    rve2.FormatTail;
    ////////////////////////////////////////////////////////////////////////////
    // Add Images to rve2 MyImageTable
    if RowCount > 0 then begin
      rve2.AddNL('', 0, 1);
      rve2.FormatTail;
      //////////////////////////////////////////////////////////////////////////
      table:= TRVTableItemInfo.CreateEx(RowCount, CellCount, rve2.RVData);
      table.BorderStyle:= rvtbRaisedColor;
      table.CellBorderStyle:= rvtbLoweredColor;
      table.BorderWidth:= 1;
      table.CellBorderWidth:= 1;
      table.CellPadding:= 5;
      table.CellVSpacing:= 1;
      table.CellHSpacing:= 1;
      table.BorderVSpacing:= 1;
      table.BorderHSpacing:= 1;
      rve2.AddItem('MyImageTable', table);
      rve2.FormatTail;
      // Init
      fMain.Table1.IndexName:= ''; // ID
      r:= 0;
      c:= -1;
      //////////////////////////////////////////////////////////////////////////
      // Locate MyImageTable
      for i:= 0 to rve2.ItemCount -1 do begin
        if (rve2.GetItemStyle(i) = rvsTable) and (rve2.GetItemText(i) = 'MyImageTable') then begin
          // Fetch Table
          table:= TRVTableItemInfo(rve2.GetItem(i));
          //
          for j:= 0 to fMain.ImageEnMView2.MultiSelectedImagesCount-1 do begin
            k:= fMain.ImageEnMView2.MultiSelectedImages[j];
            l:= fMain.ImageEnMView2.ImageID[k];
            if fMain.Table1.FindKey([l]) = True then begin
              CaptionInfo:= fMain.Table1.FieldByName('Caption').AsString;
              CaptionInfo:= Trim(CaptionInfo)+'  '+DateToStr(fMain.Table1.FieldByName('CreatedOn').AsDateTime);
              CaptionInfo:= Trim(CaptionInfo);
              //
              bm:= TBitmap.Create; // Do Not Free, gets destroyed by rve after use ???
              jpeg:= TJPEGImage.Create;
              bsF:= TEDBBlobStream.Create(TBlobField(fmain.Table1.FieldByName('JpgFrame')), bmRead);
              bsF.Seek(0, soFromBeginning);
              bsF.Position:= 0;
              jpeg.LoadFromStream(bsF);
              bm.Width:= jpeg.Width;
              bm.Height:= jpeg.Height;
              bm.Canvas.Draw(0, 0, jpeg);
              jpeg.Free;
              bsF.Free;
              //
              if c < 1 then begin
                Inc(c);
              end else begin
                Inc(r);
                c:= 0;
              end;
              // Place Cell In Edit Mode (zero based)
              table.EditCell(r, c);
              // Move caret to the beginning of this cell
              RVData:= TCustomRVFormattedData(table.Cells[r, c].GetRVData);
              RVData.SetSelectionBounds(0, RVData.GetOffsBeforeItem(0), 0, RVData.GetOffsBeforeItem(0));
              // Insert Image
              if bm <> nil then begin
                w:= rve2.TopLevelEditor.Width - (rve2.TopLevelEditor.LeftMargin + rve2.TopLevelEditor.RightMargin);
                try
                  if rve2.TopLevelEditor.InsertPicture('', bm, rvvaAbsMiddle) then begin
                    rve2.TopLevelEditor.SetCurrentItemExtraIntProperty(rvepImageHeight, 240, True);
                    rve2.TopLevelEditor.SetCurrentItemExtraIntProperty(rvepImageWidth, 320, True);
                    // Save Current Text, Para Info
                    CurTextStyleNo:= rve2.CurTextStyleNo;
                    CurParStyleNo:= rve2.CurParaStyleNo;
                    // Times New Roman, 12pt, style []
                    rve2.CurTextStyleNo:= 1;
                    // center
                    rve2.CurParaStyleNo:= 0;
                    rve2.TopLevelEditor.InsertText(CRLF+CaptionInfo, True);
                    // Restore Text, Para Info
                    rve2.CurTextStyleNo:= CurTextStyleNo;
                    rve2.CurParaStyleNo:= CurParStyleNo;
                  end;
                finally
                end;
              end;
              //
            end; // FindKey
          end; // for j
        end; // MyImageTable
      end; // for i
      fMain.Table1.IndexName:= 'ClientIDCreatedOn';
    end; // RowCount
    ////////////////////////////////////////////////////////////////////////////
    // Add RVF streams to rve2 MyNotesTable
    if ClassificationNotesCount > 0 then begin
      rve3.Style:= rvs2;
      RowCount:= ClassificationNotesCount;
      CellCount:= 1;
      rve2.AddNL('', 0, 1);
      rve2.FormatTail;
      //////////////////////////////////////////////////////////////////////////
      table2:= TRVTableItemInfo.CreateEx(RowCount, CellCount, rve2.RVData);
      table2.BorderStyle:= rvtbRaisedColor;
      table2.CellBorderStyle:= rvtbLoweredColor;
      table2.BorderWidth:= 1;
      table2.CellBorderWidth:= 1;
      table2.CellPadding:= 5;
      table2.CellVSpacing:= 1;
      table2.CellHSpacing:= 1;
      table2.BorderVSpacing:= 1;
      table2.BorderHSpacing:= 1;
      rve2.AddItem('MyNotesTable', table2);
      rve2.FormatTail;
      // Init
      Filtered:= fMain.Table2.Filtered;
      fMain.Table2.Close;
      fMain.Table2.Filtered:= False;
      fMain.Table2.IndexName:= ''; // ID
      fMain.Table2.Open;
      r:= -1;
      c:= 0;
      //////////////////////////////////////////////////////////////////////////
      // Locate MyImageTable
      for i:= 0 to rve2.ItemCount -1 do begin
        if (rve2.GetItemStyle(i) = rvsTable) and (rve2.GetItemText(i) = 'MyNotesTable') then begin
          // Fetch Table
          table2:= TRVTableItemInfo(rve2.GetItem(i));
          //
          for j:= 0 to fClassificationNotes.clClassifications.Items.Count-1 do begin
            if fClassificationNotes.clClassifications.Items[j].Checked = True then begin
              ID:= fClassificationNotes.clClassifications.Items[j].Tag;
              if fMain.Table2.FindKey([ID]) = True then begin
                // Fetch
                bsF:= TEDBBlobStream.Create(TBlobField(fmain.Table2.FieldByName('RichEditNotes')), bmRead);
                bsF.Seek(0, soFromBeginning);
                bsF.Position:= 0;
                // Copy TEDBBlobStream to rve3
                rve3.Clear;
                rve3.TopLevelEditor.InsertRVFFromStreamEd(bsF);
                rve3.InValidate;
                // Save rve3 RVF to MemoryStream
                ms:= TMemoryStream.Create;
                rve3.SaveRVFToStream(ms, False);
                // Copy TEDBBlobStream to StringStream
                mss:= TStringStream.Create('', TEncoding.Unicode); // TEncoding.Unicode TEncoding.UTF8
                bsF.Seek(0, soFromBeginning);
                bsF.Position:= 0;
                mss.CopyFrom(bsF, bsF.Size);
                bsF.Seek(0, soFromBeginning);
                bsF.Position:= 0;
                // Set Row, Cell
                Inc(r);
                c:= 0;
                // Place Cell In Edit Mode (zero based)
                table2.EditCell(r, c);
                // Move caret to the beginning of this cell
                RVData:= TCustomRVFormattedData(table2.Cells[r, c].GetRVData);
                RVData.SetSelectionBounds(0, RVData.GetOffsBeforeItem(0), 0, RVData.GetOffsBeforeItem(0));
                // Insert RVF MemoryStream FAILS
                rve2.TopLevelEditor.InsertRVFFromStreamEd(ms);
                ms.Free;
                // Insert RVF MemoryStringStream FAILS
                //rve2.TopLevelEditor.InsertRVFFromStreamEd(mss);
                mss.Free;
                // Insert RVF TEDBBlobStream FAILS
                //rve2.TopLevelEditor.InsertRVFFromStreamEd(bsF);
                bsF.Free;
              end; // FindKey
            end; // Tag
          end; // for j
        end; // MyNotesTable
      end; // for i
      fMain.Table2.Close;
      fMain.Table2.Filtered:= Filtered;
      fMain.Table2.IndexName:= 'TypeID';
      fMain.Table2.Open;
    end; // ClassificationNotesCount
    ////////////////////////////////////////////////////////////////////////////
    rve2.Invalidate; //???
    ////////////////////////////////////////////////////////////////////////////
    RVPrint1.AssignSource(rve2);
    //
    RVPrint1.LeftMarginMM:= 10;
    RVPrint1.RightMarginMM:= 10;
    RVPrint1.TopMarginMM:= 10;
    RVPrint1.BottomMarginMM:= 10;
    RVPrint1.FormatPages(rvdoALL);
    //
    if RVPrint1.PagesCount > 0 then begin
      //RVPrint1.Print('LBAnalysis', 1, False);
      fPrintPreview.rvpp.RVPrint:= RVPrint1;
      fPrintPreview.Button1Click(nil); //  Show First Page
      fPrintPreview.ShowModal;
    end; // PagesCount
    rve2.Clear;
    //
  end; // PrintIt
end;

Posted: Tue Jan 04, 2011 1:49 pm
by Sergey Tkachenko
We can get a paper width from RVPrint and scale images according to it.

But it's very difficult to search for errors in code posted in browser.
Can you send me a compilable project (as simplified as possible)?

I'll try to find bugs and add a code for picture scaling.