Webサイトにアップロードする際の.Netフレームワークを使用した1C画像処理

1C:会社は、サイズ変更や透かしを入れるために画像を操作する通常の手段を提供していません。 この機能は、商品が1Cから写真付きで輸出される場合など、オンラインストアなどでしばしば需要があります。 以前は、写真をディスクにアップロードし、コマンドラインからユーティリティを呼び出していました。 このオプションには柔軟性と速度がないことは明らかです。さらに、セキュリティとディスク上の一時ファイルの考慮に問題がある可能性があります。


提案バージョンでは、.Netフレームワークを介して、中間ファイルを作成せずにメモリ内で処理が実行されます。 処理中は、すべてのSystem.Drawingクラスを使用できます。これにより、必要に応じて通常のメソッドを使用して効果を実現できるため、メソッドに柔軟性が追加されます。 .Net framework 4.0と1C .Netブリッジ4とのインターフェースを使用します。

初期化


初期化コードは、.Net Frameworkの操作を担当する1C内にオブジェクトを作成し、System.Drawing 4番目のバージョンのビルドをロードします。

("Elisy.NetBridge4"); AddIn = New("AddIn.ElisyNetBridge4"); net = AddIn.GetNet(); net.LoadAssembly("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); 


フォーマットを変換する



.Net Framework内では、画像の処理はBitmapクラスのオブジェクトを介して行われ、1C内では、Pictureタイプが画像を処理します。 タイプImageからBitmapオブジェクトへの変換を整理する必要があります。

1C側では、Pictureタイプに対してBinaryData()メソッドが呼び出されます。 Trade Management 10.3の構成では、コードは次のようになります。

  ()   (.)   ...().();   =  ();  .(); ;  


GetPicture関数は、1CタイプのBinaryDataを返します。 次のコードで.Netタイプに変換できます。

 bytes = net.CallStatic("System.Convert", "FromBase64String", Base64String()); bitmap = net.New("System.Drawing.Bitmap", net.New("System.IO.MemoryStream", bytes)); 


画像のサイズ変更



最終的な画像の幅と高さのサイズがわかっていて、元のビットマップ画像がある場合、1Cではサイズ変更のコードはおよそ次のようになります。

 outputBitmap = net.New("System.Drawing.Bitmap", width, height); g = net.CallStatic("System.Drawing.Graphics", "FromImage", outputBitmap); g.CompositingQuality = net.New("System.Drawing.Drawing2D.CompositingQuality").HighQuality; g.SmoothingMode = net.New("System.Drawing.Drawing2D.SmoothingMode").HighQuality; g.InterpolationMode = net.New("System.Drawing.Drawing2D.InterpolationMode").HighQualityBicubic; g.Clear(net.GetStatic("System.Drawing.Color", "WhiteSmoke")); sx = width / Bitmap.Width; sy = height / Bitmap.Height; scale = (sx, sy); g.DrawImage(bitmap, ((outputBitmap.Width - scale * bitmap.Width) / 2, 0), ((outputBitmap.Height - scale * bitmap.Height) / 2, 0), (scale * bitmap.Width, 0), (scale * bitmap.Height, 0));  width >= 100  height >= 100  (net, g, watermark, width, height); ; 


このコードは、グラフィックスタイプのオブジェクトを作成し、幅と高さの寸法を持つ最終的な空のイメージoutputBitmapに基づいて、グラフィックスを使用した操作を実行できるようにします。 g.Clearを呼び出すと、画像の背景が特定の色(この場合はWhiteSmoke)で塗りつぶされます。 元の画像が指定された寸法を完全に満たさない場合は、色で塗りつぶす必要があります。 元の画像の幅と高さのパラメータと幅と高さの比率に基づいて、元の画像が結果の画像に重ねられます。

リソースを集中的に使用するgオブジェクトを最大限に活用するために、ここでテキスト文字列の透かしがパラメーターとして渡される透かしの追加プロシージャが呼び出されます。 処理の最後に明示的に呼び出すことをお勧めします。

g.Dispose();

不要になったすべてのIDisposableオブジェクト(Bitmap、outputBitmap、MemoryStream型のオブジェクト)に対してDisposeメソッドを明示的に呼び出す方が適切です。

透かしオーバーレイ



透かしはSystem.Drawingによって重ねられます。 説明する2つの方法は、gメソッドに基づいています。 MeasureString。画像に配置する予定の文字列のグラフィカル表現のサイズを返すことができます。

方法1



最初の方法は、画像の下部に透かしを入れます。 指定された透かし文字列が画像の境界に入るまで、フォントサイズは72以下から検索されます。 線は2回表示されます:半透明の黒いブラシとわずかにオフセットした半透明の白いブラシ。

方法1で取得したサンプルの透かし

 sizes = net.New("System.Collections.Generic.List", net.T("System.Int32")); sizes.Add(72); sizes.Add(36); sizes.Add(24); sizes.Add(16); sizes.Add(14); sizes.Add(12); sizes.Add(10); sizes.Add(8); sizes.Add(6); sizes.Add(4); crFont = null; crSize = net.New("System.Drawing.SizeF");  i = 0  8  crFont = net.New("System.Drawing.Font", "arial", sizes.get_Item(i), net.New("System.Drawing.FontStyle").Bold); crSize = g.MeasureString(Watermark, crFont);  crSize.Width < width  ; ; ; yPixlesFromBottom = (height * 0.05, 0); yPosFromBottom = ((height - yPixlesFromBottom) - (crSize.Height / 2)); xCenterOfImg = width / 2; StrFormat = net.New("System.Drawing.StringFormat"); StrFormat.Alignment = net.New("System.Drawing.StringAlignment").Center; semiTransBrush2 = net.New("System.Drawing.SolidBrush", net.CallStatic("System.Drawing.Color", "FromArgb", 153, 0, 0, 0)); g.DrawString(watermark, crFont, semiTransBrush2, net.New("System.Drawing.PointF", (xCenterOfImg + 1, 0), (yPosFromBottom + 1, 0)), StrFormat); semiTransBrush = net.New("System.Drawing.SolidBrush", net.CallStatic("System.Drawing.Color", "FromArgb", 153, 255, 255, 255)); g.DrawString(watermark, crFont, semiTransBrush, net.New("System.Drawing.PointF", (xCenterOfImg, 0), (yPosFromBottom, 0)), StrFormat); 


方法2



2番目の方法では、元の画像に透かしを斜めに表示します。 100番目のフォントサイズから、文字列を画像に合わせる試みが行われます。 試みが成功した場合、見つかった角度で見つかったフォントで、わずかに見える白いブラシで線が描画されます。

 font = net.New("System.Drawing.Font", "Tahoma", 40); color = net.CallStatic("System.Drawing.Color", "FromArgb", 25, 255, 255, 255); tangent = height / width; angle = ATan(tangent) * (180 / 3.1415); halfHypotenuse = Sqrt((Height * Height) + (Width * Width)) / 2;  i2 = 0  99  i = 100 - i2; font = net.New("System.Drawing.Font", "Tahoma", i, net.New("System.Drawing.FontStyle").Bold); sizef = g.MeasureString(watermark, font, net.GetStatic("System.Int32", "MaxValue")); sin = Sin(angle * (3.1415 / 180)); cos = Cos(angle * (3.1415 / 180)); opp1 = sin * sizef.Width; adj1 = cos * sizef.Height; opp2 = sin * sizef.Height; adj2 = cos * sizef.Width;  opp1 + adj1 < height  opp2 + adj2 < width  ; ; ; stringFormat = net.New("System.Drawing.StringFormat"); stringFormat.Alignment = net.New("System.Drawing.StringAlignment").Center; stringFormat.LineAlignment = net.New("System.Drawing.StringAlignment").Center; g.SmoothingMode = net.New("System.Drawing.Drawing2D.SmoothingMode").AntiAlias; g.RotateTransform((angle, 0)); g.DrawString(watermark, font, net.New("System.Drawing.SolidBrush", color), net.New("System.Drawing.PointF", (halfHypotenuse, 0), 0), stringFormat); 


2番目の方法の画像例:
方法2で取得したサンプルの透かし

Source: https://habr.com/ru/post/J176717/


All Articles