Search code examples
asp.net-mvcfacebook-graph-apidynamic-image-generation

How to generate a custom image for facebook crawler?


My web site is able to show user listings in a nice way. On the page, among other things, I display a material design sheet like this (an image, some text and some dynamic parameters of the listing):

Coludik panel

When Facebook crawls this page, I would like to supply something that looks like this (or a bit simplier) and obviously it would have to be generated dynamically since what you see is on the client side only. The thumbnail on the top left corner is too small to be given to Facebook alone. The effect would not be very pleasing.

Is it technically feasible to achieve this? Some libraries done for that?


Solution

  • I had similar problem in one of the web applications where I wanted a user to share its vote on a particular movie. What I came up with was to create a unique page for each user vote with the following meta headers:

    <meta property="og:image" content="@share_image" />
    <meta property="og:site_name" content="@SystemResource.application_name" />
    <meta property="og:url" content="@share_url" />
    <meta property="og:type" content="article" />
    <meta property="og:title" content="@share_title" />
    <meta property="og:description" content="@Model.review_text" />
    

    My @share_image contains url to an image with movie cover and user's vote (1-10) on top of it.

    I generate my @share_image when user cast a vote and it is done in the following way:

    // main image
    Image canvas = Bitmap.FromFile(configData.MainImageAbolutePath);
    
    // vote image (circles with numbers from 1 to 10)
    Bitmap smallImg = new Bitmap(configData.OverlayImageAbolutePath);
    
    // create new image
    using (Graphics gr = Graphics.FromImage(canvas))
    {
        // here you can play with quality
        gr.SmoothingMode = SmoothingMode.HighQuality;
        gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
        gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
    
        // place vote image on top of the cover using x and y coordinates
        gr.DrawImage(smallImg, new Point(configData.X, configData.Y));
    }
    // here you can play with quality
    ImageCodecInfo jgpEncoder = GetEncoderInfo(ImageFormat.Jpeg);
    Encoder myEncoder = Encoder.Quality;
    EncoderParameters myEncoderParameters = new EncoderParameters(1);
    EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 100L);
    myEncoderParameters.Param[0] = myEncoderParameter;
    
    // generate our @share_image
    canvas.Save(configData.DestinationImageAbolutePath, jgpEncoder, myEncoderParameters);  
    

    you will also need this method:

    public static ImageCodecInfo GetEncoderInfo(ImageFormat format)
    {
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
        foreach (ImageCodecInfo codec in codecs)
        {
            if (codec.FormatID == format.Guid)
            {
                return codec;
            }
        }
        return null;
    }
    

    Use this reference to Graphics class to add text and other elements: https://msdn.microsoft.com/en-us/library/system.drawing.graphics(v=vs.110).aspx