【问题标题】:How to merge two images in Xamarin Android and position it the same way like CGRect for iOS?如何在 Xamarin Android 中合并两个图像并以与 iOS 的 CGRect 相同的方式定位它?
【发布时间】:2018-03-23 10:50:04
【问题描述】:

像这样在我的项目中成功取出资源文件夹中的两张图片。

string BackGroundImage = "background_image";
string ObjectImage = "object_image";

var TheBackGroundImage = BitmapFactory.DecodeResource(Resources, Resources.GetIdentifier(BackGroundImage, "drawable", PackageName));
var TheObjectImage = BitmapFactory.DecodeResource(Resources, Resources.GetIdentifier(ObjectImage, "mipmap", PackageName));

之后我所做的是非常棘手的部分,我不知道如何完全正确。我尝试做的是创建一个以 BackgroundImage 为基础的新位图。然后我用我的第二个图像(ObjectImage)创建一个画布,该图像将位于 BackgroundImage 之上,并尝试将它们合并在一起。

Bitmap Result = Bitmap.CreateBitmap(TheBackGroundImage.Width, TheBackGroundImage.Height, TheBackGroundImage.GetConfig());
Canvas canvas = new Canvas(Result);
canvas.DrawBitmap(ObjectImage, new Matrix(), null);
canvas.DrawBitmap(ObjectImage, 79, 79, null);

这不像预期的那样工作,帆布是要走的路还是我应该看看其他东西?

如果我们看看我的 iOS 解决方案,我会这样做:

            UIImage PhoneImage = UIImage.FromFile(PhonePath);
            UIImage IconImage = UIImage.FromFile(IconPath);
            UIImage ResultImage;

            CGSize PhoneSize = PhoneImage.Size;
            CGSize IconSize = IconImage.Size;

            UIGraphics.BeginImageContextWithOptions(IconSize, false, IconImage.CurrentScale); //UIGraphics.BeginImageContextWithOptions(IconSize, false, IconImage.CurrentScale);
            UIGraphics.BeginImageContext(PhoneSize);

            CGRect Frame = (new CoreGraphics.CGRect(25, 29.5, 79, 79));
            UIBezierPath RoundImageCorner = new UIBezierPath();
            RoundImageCorner = UIBezierPath.FromRoundedRect(Frame, cornerRadius: 15);

            PhoneImage.Draw(PhoneImage.AccessibilityActivationPoint);
            RoundImageCorner.AddClip();
            IconImage.Draw(Frame);

            UIColor.LightGray.SetStroke();
            RoundImageCorner.LineWidth = 2;
            RoundImageCorner.Stroke();

            ResultImage = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();

            var documentsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            string jpgFilename = System.IO.Path.Combine(documentsDirectory, "app.png");

            NSData image = ResultImage.AsPNG();

而且它在我的第二张图片周围也可以很好地使用边框。

如何调整我的代码以成功地将两个图像合并在一起并将第二个图像定位为最好像 CGRect 一样?

【问题讨论】:

  • merge two images 你说的是什么类型的“合并”;阿尔法覆盖?一个 RGBa 组合,等等..,.... 通过显示您正在使用的 iOS 代码和可能的一两张图片,可能更容易理解您的期望。
  • @SushiHangover 用完整的 iOS 代码更新了问题。合并是指将两张透明图片放在一起并制作一张图片。

标签: xamarin xamarin.android


【解决方案1】:

试试这个:

public Bitmap mergeBitmap(Bitmap backBitmap, Bitmap frontBitmap)
{
    Bitmap bitmap = backBitmap.Copy(Bitmap.Config.Argb8888, true);
    Canvas canvas = new Canvas(bitmap);
    Rect baseRect = new Rect(0, 0, backBitmap.Width, backBitmap.Height);
    Rect frontRect = new Rect(0, 0, frontBitmap.Width, frontBitmap.Height);
    canvas.DrawBitmap(frontBitmap, frontRect, baseRect, null);
    return bitmap;
}

更新:

HereDrawBitmap 方法的介绍。我在方法中添加注释。

    public Bitmap mergeBitmap(Bitmap backBitmap, Bitmap frontBitmap)
    {
        Bitmap bitmap = backBitmap.Copy(Bitmap.Config.Argb8888, true);
        Canvas canvas = new Canvas(bitmap);

        //this Rect will decide which part of your frontBitmap will be drawn,
        //(0,0,frontBitmap.Width, frontBitmap.Height) means that the whole of frontBitmap will be drawn,
        //(0,0,frontBitmap.Width/2, frontBitmap.Height/2) means that the half of frontBitmap will be drawn.
        Rect frontRect = new Rect(0, 0, frontBitmap.Width, frontBitmap.Height);

        //this Rect will decide where the frontBitmap will be drawn on the backBitmap,
        //(200, 200, 200+ frontBitmap.Width, 200+frontBitmap.Height) means that
        //the fontBitmap will drawn into the Rect which left is 200, top is 200, and its width and
        //height are your frontBitmap's width and height.
        //I suggest the baseRect's width and height should be your fontBitmap's width and height,
        //or, your fontBitmap will be stretched or shrunk.
        Rect baseRect = new Rect(200, 200, 200+ frontBitmap.Width, 200+frontBitmap.Height);

        canvas.DrawBitmap(frontBitmap, frontRect, baseRect, null);
        return bitmap;
    }

【讨论】:

  • 好吧,那么 Rect 应该和 GCRect 一样工作吧?例如Rect frontRect = new Rect(0, 0, frontBitmap.Width, frontBitmap.Height); 会变成这样而不是new Rect( 25, 29.5, 79, 79);
  • @CarlosRodrigez,我对Ios不熟悉,如果你想把frontBitmap放在backBitmap上,你可以使用[Canvas.drawBitmap](developer.android.com/reference/android/graphics/…, android.graphics.Rect, android.graphics.Rect , android.graphics.Paint))。而在这个方法中,有一个paint参数。可以使用setXfermode方法设置PorterDuffXfermode
  • 我为你找到了this。而this 是不同的PorterDuff.Mode
  • @CarlosRodrigez,这些链接不能解决你的问题吗?
  • 我在本地保存图像并看到它的外观时遇到了问题(与此问题无关)。
猜你喜欢
  • 2020-06-22
  • 1970-01-01
  • 2012-07-29
  • 2012-03-01
  • 1970-01-01
  • 2022-01-22
  • 2012-04-05
  • 1970-01-01
相关资源
最近更新 更多