How to generate QR code with logo inside it? - java

I am developing the application for Android devices.
I want to generate QR code with logo inside it.
With ZXing I know how to generate simple QR codes like this one:
But I want to generate QR code with logo inside it.
So I want to get something like this:
Is there any way to do it?
I have no idea how to do it.
Could you help me please? May there is some ready library or example of how to do it.
Thank you!

You can add your logo it as an Image Overlay like
public BufferedImage getQRCodeWithOverlay(BufferedImage qrcode)
{
BufferedImage scaledOverlay = scaleOverlay(qrcode);
Integer deltaHeight = qrcode.getHeight() - scaledOverlay.getHeight();
Integer deltaWidth = qrcode.getWidth() - scaledOverlay.getWidth();
BufferedImage combined = new BufferedImage(qrcode.getWidth(), qrcode.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = (Graphics2D)combined.getGraphics();
g2.drawImage(qrcode, 0, 0, null);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, overlayTransparency));
g2.drawImage(scaledOverlay, Math.round(deltaWidth/2), Math.round(deltaHeight/2), null);
return combined;
}
private BufferedImage scaleOverlay(BufferedImage qrcode)
{
Integer scaledWidth = Math.round(qrcode.getWidth() * overlayToQRCodeRatio);
Integer scaledHeight = Math.round(qrcode.getHeight() * overlayToQRCodeRatio);
BufferedImage imageBuff = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_ARGB);
Graphics g = imageBuff.createGraphics();
g.drawImage(overlay.getScaledInstance(scaledWidth, scaledHeight, BufferedImage.SCALE_SMOOTH), 0, 0, new Color(0,0,0), null);
g.dispose();
return imageBuff;
}
Please refer this post & github for more info

I created the following Kotlin Extention, which adds a Bitmap to the centre of another Bitmap:
fun Bitmap.addOverlayToCenter(overlayBitmap: Bitmap): Bitmap {
val bitmap2Width = overlayBitmap.width
val bitmap2Height = overlayBitmap.height
val marginLeft = (this.width * 0.5 - bitmap2Width * 0.5).toFloat()
val marginTop = (this.height * 0.5 - bitmap2Height * 0.5).toFloat()
val canvas = Canvas(this)
canvas.drawBitmap(this, Matrix(), null)
canvas.drawBitmap(overlayBitmap, marginLeft, marginTop, null)
return this
}
Can find my full solution here.

In Kotlin with zxing library and overlay from assets folder.
The correction needs to be made because the overlay will hide some part of the QR Code;
Class MatrixToImageWriter is from: https://github.com/kenglxn/QRGen
private fun generateQrCodeWithOverlay(qrCodeData: String): Bitmap? {
val hints = HashMap<EncodeHintType?, Any?>()
// The Error Correction level H provide a QR Code that can be covered by 30%
hints[EncodeHintType.ERROR_CORRECTION] = ErrorCorrectionLevel.H
val writer = QRCodeWriter()
return try {
// Create a QR Code from qrCodeData and 512 by 512 pixels, same size as my Logo
val encodedQrCode = writer.encode(qrCodeData, BarcodeFormat.QR_CODE, 512, 512, hints)
var qrCodeBitmap: Bitmap = MatrixToImageWriter.toBitmap(encodedQrCode)
val qrCodeCanvas = Canvas(qrCodeBitmap)
// Used to resize the image
val scaleFactor = 4
val logo =
BitmapFactory.decodeStream(app.assets.open("path/to/your/logo.png"))
// Resizing the logo increasing the density to keep it sharp
logo.density = logo.density * scaleFactor
val xLogo = (512 - logo.width / scaleFactor) / 2f
val yLogo = (512 - logo.height / scaleFactor) / 2f
qrCodeCanvas.drawBitmap(logo, xLogo, yLogo, null)
qrCodeBitmap
} catch (e: Exception) {
// handle errors
null
}
}

There is plenty online QR code generator, such as https://app.aotol.com/qr/api
You can just reference the QR image url to it such as
<img src="https://app.aotol.com/qr/api?qr_content=https://wwww.google.com&qr_logo=https://blog.hubspot.com/hubfs/image8-2.jpg">

Related

How to get Bitmap from session.update() in ARCore [Android Studio]

I am trying to get a Bitmap from the current frame of my ARSession with ARCore. But it always equals null. I've already been searching the web for quite a while but cannot figure out what I am doing wrong.
try {
capturedImage = mFrame.acquireCameraImage();
ByteBuffer buffer = capturedImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length,null);
if (bitmap == null)
Log.e(TAG,"Bitmap was NOT initialized!");
} catch(Exception e){
}
I am getting mFrame from onDrawFrame of my GLSurfaceView which I use to display the camera image. Everything works just fine except that my Bitmap equals null.
I am using a Button, so that only a single Frame is being used, as follows:
scanButton = (Button) findViewById(R.id.scanButton);
scanButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
checkbox = false;
if (capturedImage!=null) capturedImage.close();
BitmapMethod();
}
});
capturedImage, buffer and bytes all do not equal null.
Is there probably something wrong with mFrame.acquireCameraImage()?
Thanks a lot
Is there probably something wrong with mFrame.acquireCameraImage()?
No, mFrame.acquireCameraImage() works as intended.
But it always equals null
The Bitmap will always equal null since bitmap factory does not understand the image data that is passed to it.
The method mFrame.acquireCameraImage() responds with an object of type Image that is in the YUV format or YCbCr. These types of images have 3 planes which is explained here very nicely. The ByteArray contained in these planes may be read directly by a CPU/GPU in native code. BitmapFactory cannot read this type of data. Hence, you need to convert this YUV image into something else.
For that, you need to use YuvImage class to create an instance of YUV & then convert it into JPEG using the compressToJpeg method. Once you have the byteArray from this, you can simply do what you're doing above. Use BitmapFactory to convert it into Bitmap and add it to your ImageView.
Note : YUV has 3 planes. Create a single bytearray from all planes & then pass it to YUV constructor. Though not elaborate, it should look something similar to this :
//The camera image received is in YUV YCbCr Format. Get buffers for each of the planes and use them to create a new bytearray defined by the size of all three buffers combined
val cameraPlaneY = cameraImage.planes[0].buffer
val cameraPlaneU = cameraImage.planes[1].buffer
val cameraPlaneV = cameraImage.planes[2].buffer
//Use the buffers to create a new byteArray that
val compositeByteArray = ByteArray(cameraPlaneY.capacity() + cameraPlaneU.capacity() + cameraPlaneV.capacity())
cameraPlaneY.get(compositeByteArray, 0, cameraPlaneY.capacity())
cameraPlaneU.get(compositeByteArray, cameraPlaneY.capacity(), cameraPlaneU.capacity())
cameraPlaneV.get(compositeByteArray, cameraPlaneY.capacity() + cameraPlaneU.capacity(), cameraPlaneV.capacity())
val baOutputStream = ByteArrayOutputStream()
val yuvImage: YuvImage = YuvImage(compositeByteArray, ImageFormat.NV21, cameraImage.width, cameraImage.height, null)
yuvImage.compressToJpeg(Rect(0, 0, cameraImage.width, cameraImage.height), 75, baOutputStream)
val byteForBitmap = baOutputStream.toByteArray()
val bitmap = BitmapFactory.decodeByteArray(byteForBitmap, 0, byteForBitmap.size)
imageView.setImageBitmap(bitmap)
That's just a rough code. It has scope for improvement perhaps. Also refer here.
I also winded up recreating the same situation as you were facing. I was getting the Image object as Null.
After some research, I found the problem was in the flow of the logic.
I then wrote the following code and it solved my issue:
I defined the following boolean to be set to capture the current frame on the button click:
private static boolean captureCurrentFrame = false;
This code I wrote in the onClick() function to get the current frame's RGB and Depth Image:
public void captureFrame(View view){
Toast.makeText(getApplicationContext(),"Capturing depth and rgb photo",Toast.LENGTH_SHORT).show();
captureCurrentFrame = true;
}
This section I wrote in onDrawFrame() method just after getting the frame from session.update():
if(captureCurrentFrame) {
RGBImage = frame.acquireCameraImage();
DepthImage = frame.acquireDepthImage();
Log.d("Image","Format of the RGB Image: " + RGBImage.getFormat());
Log.d("Image","Format of the Depth Image: " + DepthImage.getFormat());
RGBImage.close();
DepthImage.close();
captureCurrentFrame = false;
}
Reason for getting Null in my case was the code in the onClick listener was getting triggered before going through the onDraw() method, as a result of which the Images were not stored in the variables.
Therefore, I shifted the logic to onDraw() and triggered that flow through the boolean variable that is set by the listener.
I don't know if there is anybody still looking for the answer, but this is my code.
Image image = mFrame.acquireCameraImage();
byte[] nv21;
// Get the three planes.
ByteBuffer yBuffer = image.getPlanes()[0].getBuffer();
ByteBuffer uBuffer = image.getPlanes()[1].getBuffer();
ByteBuffer vBuffer = image.getPlanes()[2].getBuffer();
int ySize = yBuffer.remaining();
int uSize = uBuffer.remaining();
int vSize = vBuffer.remaining();
nv21 = new byte[ySize + uSize + vSize];
//U and V are swapped
yBuffer.get(nv21, 0, ySize);
vBuffer.get(nv21, ySize, vSize);
uBuffer.get(nv21, ySize + vSize, uSize);
int width = image.getWidth();
int height = image.getHeight();
ByteArrayOutputStream out = new ByteArrayOutputStream();
YuvImage yuv = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
yuv.compressToJpeg(new Rect(0, 0, width, height), 100, out);
byte[] byteArray = out.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);

write a custom name on the top of the picture taken by android cam

If this question is repeated then let me know the link of original question because i enable to findout the good link for resolve my current problem.
I am working on android camera I able to take Picture's from my app. But I want to write name on the top of taken picture. i enable to find out how can i resolve this issue.
Sorry for i don't have any code for take reference.....
any help will be appreciated and i want to pay my thank in advance to all of you.
Try following code.
public Bitmap drawTextToBitmap(Bitmap bitmap, String mText) {
try {
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if(bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
// new antialised Paint
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// text color - #3D3D3D
paint.setColor(Color.rgb(110,110, 110));
// text size in pixels
paint.setTextSize((int) (12 * scale));
// text shadow
paint.setShadowLayer(1f, 0f, 1f, Color.DKGRAY);
// draw text to the Canvas center
Rect bounds = new Rect();
paint.getTextBounds(mText, 0, mText.length(), bounds);
int x = (bitmap.getWidth() - bounds.width())/6;
int y = (bitmap.getHeight() + bounds.height())/5;
canvas.drawText(mText, x * scale, y * scale, paint);
return bitmap;
} catch (Exception e) {
return null;
}
}

Generate thumbnail and fill empty space with color

Is it possible to implement the first example with Scalr?
My code is the following:
BufferedImage thumbnail = Scalr.resize(ImageIO.read(sourceFile), Scalr.Method.ULTRA_QUALITY, Scalr.Mode.FIT_TO_WIDTH,
width, height, Scalr.OP_ANTIALIAS);
ImageIO.write(thumbnail, destinationfile.getExtension(), destinationfile);
What I want is to receive the image like this:
where the blue bars are the space I want to fill with the color.
Thank you
Update: maybe it is possible to implement with Thumbnailator?
Just done! Perhaps it can help you!
public static BufferedImage resizeAndCrop(BufferedImage bufferedImage) throws IOException {
int himg = bufferedImage.getHeight();
int wimg = bufferedImage.getWidth();
double rateh = himg/dim;
double ratew = wimg/dim;
double rate = ratew;
if(rateh>ratew)
rate = rateh;
int dimhimg = (int) (himg/rate);
int dimwimg = (int) (wimg/rate);
double startw = dim/2 - dimwimg/2;
double starth = dim/2 - dimhimg/2;
BufferedImage tThumbImage = new BufferedImage( dim, dim, BufferedImage.TYPE_INT_RGB );
Graphics2D tGraphics2D = tThumbImage.createGraphics(); //create a graphics object to paint to
tGraphics2D.setBackground( Color.WHITE );
tGraphics2D.setPaint( Color.WHITE );
tGraphics2D.fillRect( 0, 0, dim, dim );
tGraphics2D.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
tGraphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
tGraphics2D.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
tGraphics2D.drawImage( bufferedImage, (int)startw, (int)starth, dimwimg, dimhimg, null ); //draw the image scaled
File ff = new File(path + "jdata/tmp/prova.jpg");
ImageIO.write( tThumbImage, "JPG", ff); //write the image to a file
BufferedImage croppedContainMethod = ImageIO.read(ff);
return croppedContainMethod;
}
Nobody has idea so I will publish my solution...
I decided to continue to use Scalr (I didn't checked the Thumbnailator's last version but the previous ones failed on big pictures).
So first of all I call resize method, and then, if sizes of the new thumbnail are bigger then given ones I call crop method that crops a thumbnail by the center.. The code is the following:
BufferedImage thumbnail = Scalr.resize(sourceFile, Scalr.Method.ULTRA_QUALITY, Scalr.Mode.AUTOMATIC, destinationSize.width, destinationSize.height);
if (thumbnail.getWidth() > destinationSize.width)
thumbnail = Scalr.crop(thumbnail, (thumbnail.getWidth() - destinationSize.width) / 2, 0, destinationSize.width, destinationSize.height);
else if (thumbnail.getHeight() > destinationSize.height)
thumbnail = Scalr.crop(thumbnail, 0, (thumbnail.getHeight() - destinationSize.height) / 2, destinationSize.width, destinationSize.height);
It is not ideal, but at least it handles 'wide' images after generation of thumbnails

Bitmap Memory Error Android

I am making an Android game, but when I load my Bitmaps, I get a memory error. I know that this is caused by a very large Bitmap (it's the game background), but I don't know how I could keep from getting a "Bitmap size extends VM Budget" error. I can't rescale the Bitmap to make it smaller because I can't make the background smaller. Any suggestions?
Oh yeah, and here's the code that causes the error:
space = BitmapFactory.decodeResource(context.getResources(),
R.drawable.background);
space = Bitmap.createScaledBitmap(space,
(int) (space.getWidth() * widthRatio),
(int) (space.getHeight() * heightRatio), false);
You're going to have to sample down the image. You can't "scale" it down smaller than the screen obviously, but for small screens etc it doesn't have to be as high resolution as it is for big screens.
Long story short you have to use the inSampleSize option to downsample. It should actually be pretty easy if the image fits the screen:
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
final Display display = wm.getDefaultDisplay();
final int dimension = Math.max(display.getHeight(), display.getWidth());
final Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
InputStream bitmapStream = /* input stream for bitmap */;
BitmapFactory.decodeStream(bitmapStream, null, opt);
try
{
bitmapStream.close();
}
catch (final IOException e)
{
// ignore
}
final int imageHeight = opt.outHeight;
final int imageWidth = opt.outWidth;
int exactSampleSize = 1;
if (imageHeight > dimension || imageWidth > dimension)
{
if (imageWidth > imageHeight)
{
exactSampleSize = Math.round((float) imageHeight / (float) dimension);
}
else
{
exactSampleSize = Math.round((float) imageWidth / (float) dimension);
}
}
opt.inSampleSize = exactSampleSize; // if you find a nearest power of 2, the sampling will be more efficient... on the other hand math is hard.
opt.inJustDecodeBounds = false;
bitmapStream = /* new input stream for bitmap, make sure not to re-use the stream from above or this won't work */;
final Bitmap img = BitmapFactory.decodeStream(bitmapStream, null, opt);
/* Now go clean up your open streams... : ) */
Hope that helps.
This may help you: http://developer.android.com/training/displaying-bitmaps/index.html
From the Android Developer Website, a tutorial on how to efficiently display bitmaps + other stuff. =]
I don't understand why are you using ImageBitmap? for background. If its necessary , its okay. Otherwise please use Layout and set its background because you are using background image.
This is important. (Check Android docs. They have clearly indicated this issue.)
You can do this in following way
Drawable d = getResources().getDrawable(R.drawable.your_background);
backgroundRelativeLayout.setBackgroundDrawable(d);
In most android devices the Intent size equals 16MB. You MUST Follow these instructions Loading Large Bitmap Efficiently

Google App Engine & Java : images thumb

I'm trying to resize and crop images into Google App engine in order to create thumbnails
I would like to be able to create 200x150 thumbs from any size.
This is the code I'm using so far now I need to crop it so it doesn't go bigger than 200x150:
Image oldImage = ImagesServiceFactory.makeImage(picture);
//Create the Image Service Factory and the Resize Transform
ImagesService imagesService = ImagesServiceFactory.getImagesService();
int w = 0;
int h = 0;
if (oldImage.getWidth() > oldImage.getHeight()) {
w = 1000;
h = height;
} else {
h = 1000;
w = width;
}
Transform resize = ImagesServiceFactory.makeResize(w, h);
//Resize The Image using the transform created above
Image resizedImage = imagesService.applyTransform(resize, oldImage);
Transform crop = ImagesServiceFactory.makeCrop(0.0, 0.0, width / resizedImage.getHeight(), height / resizedImage.getHeight());
Image cropedImage = imagesService.applyTransform(crop, resizedImage);
//Serve the newly transformed image
return cropedImage.getImageData();
Thanks !
I serve thumbnails with google app engine dynamically using getServingUrl
That can resize and crop storing only one image doing the resize and crop dynamically. Since I'm very satisfied with that solution I hope it can work for you too.
Your oldImage is less than 200px wide.

Categories

Resources