I want to use custom font in Flutter Image.drawString

1.9k Views Asked by At

This is about Flutter, Dart, Image, specifically drawString function.

First of all, what I am trying to do is watermark the picture taken with the address and time. I mean not just placing text over the image but actually merge it with picture so that the user can submit the picture as a proof that he's done a certain task in the right spot and right time.

To do so. I found the right function drawString(), but the problem is it only supports arial font. Since I have to write in Korean, I need to use my own font. Is there any one who tried this before. I tried readFont method but couldn't make it. Anyone who knows?

import 'package:image/image.dart' as img;

img.drawString(image1, img.readFont('My OWN Font', image1), 30, 30, str_to_write, color:0xFF000000);

====================================== before I call the function, I tried to make the bitmap font like this as stated in the Image package, but failed to make it. (So, I placed the zip file in the same directory and also in the assets folder)

       String fileName = 'GmarketSansTTFMedium.ttf.zip';
       File file = File('$fileName');
       List<int> bytes = file.readAsBytesSync();
       print(bytes);
1

There are 1 best solutions below

0
MaheshPeri19 On

You can find steps to convert .ttf to .zip in “image” package in below file path. lib ==> src ==> bitmap_font.dart

A bitmap font that can be used with [drawString] and [drawChar] functions. If you want use own fonts, follow with below steps:

1. Get your .ttf file - important is to select file with specific style which you want
         for example when you download .ttf file from google fonts: select file from /static folder
         example name: Roboto-Black.ttf
2. Convert ttf file to fnt zip with this link: "https://ttf2fnt.com/" and dont forgot to  mention required font size like 40px, 60px. 
3. Download zip file and drag to your project assets folder and mention path in .yaml file
4. Call below method whereever you want :

const int kYellowColorIntValue = 0xffffff00; 
const int kCyanColorIntValue = 0xff00ffff; 

void getWaterMarkTextOnImage() async 
{
  var decodeImg = img.decodeImage(<your origianl photo UInt8List>);
  ByteData fBitMapFontData = await loadAssetFont();
  
  img.BitmapFont requiredRobotoFont = img.BitmapFont.fromZip(fBitMapFontData.buffer.asUint8List());

  // IMPORTANT NOTE : Assiged color is Cyan. But required color is Yellow.
  // It is taking yellow as cyan and cyan as yellow.
  // set X, Y axis as per your requirement
  img.drawString(decodeImg!, requiredRobotoFont, 80, decodeImg.height - 200,
    requiredLatLongString!,
    color: kCyanColorIntValue);
  
  img.drawString(decodeImg, requiredRobotoFont, 80, decodeImg.height - 130,
    requiredTimeStampString!,
    color: kCyanColorIntValue); // KYellowColorIntValue
  var encodeImage = img.encodeJpg(decodeImg, quality: 100);

  // Take finalImageFile global variable and assign to image widget
  File? finalImageFile = File(<your image captured path>)..writeAsBytesSync(encodeImage);
}

Future<ByteData> loadAssetFont() async 
{
  ByteData imageData = await rootBundle.load(kRobotoBitmapZipFilePath);
  setState(() {}); 
  return imageData;
}

5. Create Image widget here.
Widget getCapturedPhotoWidget()
{
  double aspRatio, imgHeight = 0.0;
  if (<captured pic is portrait mode>) {
    // portrait
    aspRatio = (1 / widget.overlay.ratio!);
    imgHeight = finalImageSize!.width.toDouble();
  } else {
    // landscape
    aspRatio = widget.overlay.ratio! * 1.5;
    imgHeight = finalImageSize!.height.toDouble() / 5;
  }
  return Center(
    child: Container(
        height: imgHeight, // finalImageSize!.width.toDouble(),
        margin: EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 10),
        child: ClipRRect(
          borderRadius: BorderRadius.circular(16.0),
          child: AspectRatio(
            aspectRatio: aspRatio, // widget.overlay.ratio!,
            child: finalImageFile != null
                ? Image.file(
                    finalImageFile!,
                    fit: BoxFit.fill,
                  )
                : Offstage(),
          ),
        )),
  );
}

Thats it for using custom font of bitmap Happy Coding!!!