BLOB to Bitmap in axapta - blob

I have declared a variable as
Bitmap image;
Container storeImg;
I am storing the image as
storeImg+= image;
the image is stored as BLOB type in container
Later On when I try to retrieve the image in a Bitmap variable e.g.
Bitmap image2;
image2 = conpeek(storeImg,1);
I get an "operand mismatch error"
My question is I have declared the image as bitmap and stored in a container then why the error when I am trying to retrieve the same in a bitmap datatype only?
Thanks in advance.

The Bitmap extended data type is really a container.
Adding containers gives concatenation which may be (part of) your problem:
static void BitmapTest(Args _args)
{
Bitmap image1 = [1,2,3];
Bitmap image2 = [7,8,9];
Container storeImg;
;
storeImg += image1;
storeImg += image2;
print conlen(storeImg);
pause;
}
This prints 6, not 2 as you may assume.
Also blob and container is not the same thing:
static void BitmapTest(Args _args)
{
BinData b = new BinData();
Bitmap image1 = b.getData();
Bitmap image2 = b.getData();
Container storeImg;
;
storeImg += image1;
storeImg += image2;
image2 = conpeek(storeImg,1);
pause;
}
This will fail because storeImg contains two blob values.
Change the assignments to:
storeImg += [image1];
storeImg += [image2];
This will work, because now storeImg contains two container values (containing a blob).
Also see Load and Save file from and to container field

Related

android how to scale down a bitmap and keep its aspect ration

using 3rd party library which returns a bitmap. in the app it would like to scale down the bitmap.
static public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
matrix, false);
return resizedBitmap;
}
===
Bitmap doScaleDownBitmap() {
Bitmap bitmap = libGetBitmap(); // got the bitmap from the lib
int width = bitmap.getWidth();
int height = bitmap.getHeight();
if (width > 320 || height > 160) {
bitmap = getResizedBitmap(bitmap, 320, 160);
}
System.out.println("+++ width;"+width+", height:"+height+ ", return bmp.w :"+bitmap.getWidth()+", bmp.h:"+bitmap.getHeight());
return bitmap;
}
the log for a test bitmap (348x96):
+++ width;348, height:96, return bmp.w :320, bmp.h:160
looks like the resized bitmap does not scale properly, shouldnt it be 320 x 88 to maintain the aspect ratio?
(it did from (348x96) ==> (320x160))
saw android sample
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
how to apply it if has the bitmap already?
or what is the correct way to scale down a bitmap?
EDIT:
this one could keep the aspect ration and one of the desired dimensions (either width or height) will be used for the generated bitmap. basically CENTER_FIT.
However it does not generate the bitmap with both desired width and height.
e.g. would like to have a new bitmap of (w:240 x h:120) from a src bitmap of (w:300 x h:600), it will map to (w:60 x h:120).
I guess it needs extra operation on top of this new bitmap if want the new bitmap has (w:240 x h:120).
is there a simpler way to do it?
public static Bitmap scaleBitmapAndKeepRation(Bitmap srcBmp, int dstWidth, int dstHeight) {
Matrix matrix = new Matrix();
matrix.setRectToRect(new RectF(0, 0, srcBmp.getWidth(), srcBmp.getHeight()),
new RectF(0, 0, dstWidth, dstHeight),
Matrix.ScaleToFit.CENTER);
Bitmap scaledBitmap = Bitmap.createBitmap(srcBmp, 0, 0, srcBmp.getWidth(), srcBmp.getHeight(), matrix, true);
return scaledBitmap;
}
When you Scale-Down the bitmap, if width and height are not divisible by scale, you should expect tiny change in ratio. if you don't want that, first crop the image to be divisible and then scale.
float scale=0.5f;
scaledBitmap=Bitmap.createScaledBitmap(bitmap,
(int)(bitmap.width()*scale),
(int)(bitmap.height()*scale),
true); //bilinear filtering
Found a way, I am sure there is better one
public static Bitmap updated_scaleBitmapAndKeepRation(Bitmap srcBitmap, int targetBmpWidth,
int targetBmpHeight) {
int width = srcBitmap.getWidth();
int height = srcBitmap.getHeight();
if (targetBmpHeight > 0 && targetBmpWidth > 0 && (width != targetBmpWidth || height != targetBmpHeight)) {
// create a canvas with the specified bitmap to draw into.
Bitmap scaledImage = Bitmap.createBitmap(targetBmpWidth, targetBmpHeight, Bitmap.Config.ARGB_4444);
Canvas canvas = new Canvas(scaledImage);
// draw transparent background color
Paint paint = new Paint();
paint.setColor(Color.TRANSPARENT);
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);
// draw the source bitmap on canvas and scale the image with center_fit (the source image's larger side is mapped to the corresponding desired dimensions, and the other side scaled with aspect ration)
Matrix matrix = new Matrix();
matrix.setRectToRect(new RectF(0, 0, srcBitmap.getWidth(), srcBitmap.getHeight()),
new RectF(0, 0, targetBmpWidth, targetBmpHeight),
Matrix.ScaleToFit.CENTER);
canvas.drawBitmap(srcBitmap, matrix, null);
return scaledImage;
} else {
return srcBitmap;
}
}
The result screenshot:
The 1st image is the src (w:1680 x h:780),
2nd is from the scaleBitmapAndKeepRation() in the question part, which has scaled image but with dimensions (w:60 x h:120) not in desired dimensions (w: 240 x h:120),
3rd is the one does not keep the aspect ration, although has the dimension right.
4th is from the updated_scaleBitmapAndKeepRation() which has the desired dimensions and the image is center_fit and keep the aspect ratio.

cryptage et decryptage rsa sur une image utilisant java netbeans

I'm working on an application that can encrypt and decrypt an image (specific selection ) using RSA algorithm, all works well but some pixels are behaving strangely and I can't understand why! I use the same parameters to encrypt/decrypt and save the image and yet, when I create the new image, and try to read the pixels in crypted zone, I don't get the pixel that my program showed me before.
File img = new File (Path);
bf1 = ImageIO.read(img);
marchdanslImage(bf1,captureRect); // only selected rectangle (captureRect) from image will be treated
///////the function i called before
private void marchdanslImage(BufferedImage image , Rectangle REC) throws IOException {
bf2 = new BufferedImage(REC.width, REC.height, BufferedImage.TYPE_INT_RGB); //this image gonna contain the pixels after encryption
for (int i = y; i < h; i++) {
for (int j = x; j < w; j++) {
int pixel = image.getRGB(j, i);//orginal values
printPixelARGB(pixel,j,i); //here i call the code to crypt or decrypt
bf2.setRGB(j-x,i-y, rgb); //new values
} }
}
the code of the function printPixelARGB:
public void printPixelARGB(int pixel,int i , int j) {
r[i][j] = (pixel >> 16) & 0xff; // original values
rr[i][j] = RSA_crypt_decrypt(r[i][j], appel);//values after treatment
g[i][j] = (pixel >> 8) & 0xff;
gg[i][j] = RSA_crypt_decrypt(g[i][j], appel);
b[i][j] = (pixel) & 0xff;
bb[i][j] = RSA_crypt_decrypt(b[i][j], appel);
rgb = rr[i][j];// new values on rgb to be set in bf2
rgb = (rgb << 8) + gg[i][j];
rgb = (rgb << 8) + bb[i][j];
}
and finally to save my work:
public void save_image()
{
Graphics2D g;
g = (Graphics2D) bf1.getGraphics();
g.drawImage(bf2, captureRect.x, captureRect.y, captureRect.width, captureRect.height, null);
g.dispose();
//i draw the crypted pixels on my original image and create new image
File outputFile = new File("C:/USERS/HP/DesKtop/output.jpg");
try {
ImageIO.write(bf1, "jpg", outputFile);
} catch (IOException ex) {
Logger.getLogger(MenuGenerale2.class.getName()).log(Level.SEVERE, null, ex);
}
}
So far everything is working, but when open the image I created, and try to decrypt, the values I get are not the same, after treatment!
Is it because of the saving part? When I try it on a white image it does not work correctly, but on another image it does not at all! It's been 3 weeks couldn't solve this problem... I really really need help.
Here is the link of my application:
www.fichier-rar.fr/2016/04/23/cryptagersa11/
The problem is that you are saving the image with JPEG compression. JPEG compression does not preserve data exactly: it is a lossy compression.
If you used, say, BMP or PNG files, the problem would would not happen.
You might want to investigate steganography, although I suspect it is the opposite of what you want to achieve

PDFBox not returning the correct size of an image

I am new to PDFBox and am stuck at finding the height of an image in inches. After a couple of searches, this is the piece of code that I am working with:
PDResources resources = aPdPage.findResources();
graphicsState = new PDGraphicsState(aPdPage.findCropBox());
pageWidth = aPdPage.findCropBox().getWidth() / 72;
pageHeight = aPdPage.findCropBox().getHeight() / 72;
#SuppressWarnings("deprecation")
Map<String, PDXObjectImage> imageObjects = resources.getImages();
if (null == imageObjects || imageObjects.isEmpty())
return;
for (Map.Entry<String, PDXObjectImage> entryxObjects : imageObjects.entrySet()) {
PDXObjectImage image = entryxObjects.getValue();
// System.out.println("bits per component: " + image.getBitsPerComponent());
Matrix ctmNew = graphicsState.getCurrentTransformationMatrix();
float imageXScale = ctmNew.getXScale();
float imageYScale = ctmNew.getYScale();
System.out.println("position = " + ctmNew.getXPosition() + ", " + ctmNew.getYPosition());
// size in pixel
System.out.println("size = " + image.getWidth() + "px, " + image.getHeight() + "px");
// size in page units
System.out.println("size = " + imageXScale + "pu, " + imageYScale + "pu");
// size in inches
imageXScale /= 72;
imageYScale /= 72;
System.out.println("size = " + imageXScale + "in, " + imageYScale + "in");
// size in millimeter
imageXScale *= 25.4;
imageYScale *= 25.4;
System.out.println("size = " + imageXScale + "mm, " + imageYScale + "mm");
System.out.printf("dpi = %.0f dpi (X), %.0f dpi (Y) %n", image.getWidth() * 72 / ctmNew.getXScale(), image.getHeight() * 72 / ctmNew.getYScale());
}
But the value is not coming correctly in inches. The imageXScale value in pu is coming to be 0.1 always.
Any help would be appreciated.
First of all you need to know how bitmap images usually are used in PDFs:
In a PDF a page object has a collection of so called resources, among them bitmap image resources, font resources, ...
You can inspect these resources like you currently do:
PDResources resources = aPdPage.findResources();
#SuppressWarnings("deprecation")
Map<String, PDXObjectImage> imageObjects = resources.getImages();
if (null == imageObjects || imageObjects.isEmpty())
return;
for (Map.Entry<String, PDXObjectImage> entryxObjects : imageObjects.entrySet())
{
PDXObjectImage image = entryxObjects.getValue();
System.out.println("size = " + image.getWidth() + "px, " + image.getHeight() + "px");
}
But this only gives you the pixel dimension of the images as they are available in the page resources.
When such an resource is painted onto the page, the operation doing this actually first scales it down to a 1x1 unit square and paints this scaled down version.
The reason why you on screen and on paper have images of reasonable size, is that the way painting operators work in PDFs is influenced by the so called current graphics state. This graphics state contains information like the current fill color, line widths, etc... In particular it also contains the so called current transformation matrix which defines how everything some operation draws shall be stretched, rotated, skewed, translated, ... transformed.
The usual sequence of operations when drawing a bitmap image looks like this:
...
store a temporary copy of the current graphics state,
change the current transformation matrix by a scaling transformation which multiplies the x coordinate by the desired widths and the y coordinate by the desired height of the image to draw,
draw the image referenced in the resources, and
restore the current graphics state to the temporarily stored values,
...
Thus, to know the dimensions of the image on the page, you have to know the current transformation matrix as it is when the image drawing operation is executed.
Your code, on the other hand, uses the current transformation matrix from a freshly instantiated graphics state with all values at defaults. Thus, your code prints the false information on how the image is scaled on the page.
To get the correct information, you have to parse the sequence of operations executed for creating the document page.
This is exactly what the PDFBox PrintImageLocations example does: It processes the page content stream (which contains all those operations), updating a copy of the values of the current graphics state, and when it sees an operation for drawing a bitmap image, it uses the value of the current transformation matrix at that very moment:
protected void processOperator( PDFOperator operator, List arguments ) throws IOException
{
String operation = operator.getOperation();
if( INVOKE_OPERATOR.equals(operation) )
{
COSName objectName = (COSName)arguments.get( 0 );
Map<String, PDXObject> xobjects = getResources().getXObjects();
PDXObject xobject = (PDXObject)xobjects.get( objectName.getName() );
if( xobject instanceof PDXObjectImage )
{
PDXObjectImage image = (PDXObjectImage)xobject;
PDPage page = getCurrentPage();
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
double pageHeight = page.getMediaBox().getHeight();
System.out.println("*******************************************************************");
System.out.println("Found image [" + objectName.getName() + "]");
Matrix ctmNew = getGraphicsState().getCurrentTransformationMatrix();
...
[calculate dimensions and rotation of image on page]
...
Thus, for your task that PDFBox example should be a good starting point.

Windows Store App: set an image as a background for an UI element

Sorry for asking a really basic question, but it's probably the first time for a number of years I feel really confused.
Windows provides two set of controls: Windows.UI.Xaml namespace (I thinks this is referred as Metro), used for Windows Store Apps, and System.Windows (WPF) for Desktop.
Since I am going to develop Windows Store Apps mainly for Windows 8.1 and Windows 10 phones, I will have to stick to Windows.UI.Xaml, and this has not only a separate set of UI elements, but also separate set of bitmaps, brushes, etc. (Windows.UI.Xaml.Media vs System.Windows.Media).
I found that Windows.UI.Xaml provides a very limited support for graphics, much less than provided by WPF, Android or (even!) iOS platform. To start with, I got stuck with a simple task: tiling a background!
Since Windows.UI.Xaml.Media.ImageBrush do not support tiling, I wanted to to do that "manually". Some sites suggest making numerous number of children, each holding a tile. Honestly, it looks as a rather awkward approach to me, so I decided to do it in what appears a more natural way: create an off-screen tiled image, assign it to a brush and assign the brush as the background for a panel.
The tiling code is rather straightforward (it probably has mistakes, possibly won't even not run on a phone, because of some unavailable classes used).
int panelWidth = (int) contentPanel.Width;
int panelHeight = (int) contentPanel.Height;
Bitmap bmpOffscreen = new Bitmap(panelWidth, panelHeight);
Graphics gOffscreen = Graphics.FromImage(bmpOffscreen);
string bmpPath = Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path, "Assets/just_a_tile.png");
System.Drawing.Image tile = System.Drawing.Image.FromFile(bmpPath, true);
int tileWidth = tile.Width;
int tileHeight = tile.Height;
for (int y = 0; y < panelHeight; y += tileHeight)
for (int x = 0; x < panelWidth; x += tileWidth)
gOffscreen.DrawImage(tile, x, y);
Now I presumably have the tiled image in bmpOffscreen. But how assign it to a brush? To do that I need to convert Bitmap to BitmapSource, while I couldn't find something similar to System.Windows.Imaging.CreateBitmapSourceFromHBitmap available for WPF structure!
Well, first of all System.Drawing namespace is not available in Windows Universal Platform, so you won't be able to use Bitmap class
But, all hope is not lost - you can use
Windows.UI.Xaml.Media.Imaging.WriteableBitmap
If you look at example included on this page, you will see that at one point image data is extracted to a byte array - all you need to do is copy it according to your needs
Please let me know if you want me to include a complete code sample.
Edit:
StorageFile file = await StorageFile.GetFileFromPathAsync(filePath);
Scenario4WriteableBitmap = new WriteableBitmap(2000, 2000);
// Ensure a file was selected
if (file != null)
{
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
int columns = 4;
int rows = 4;
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
// Scale image to appropriate size
BitmapTransform transform = new BitmapTransform()
{
ScaledHeight = Convert.ToUInt32(Scenario4ImageContainer.Height),
ScaledWidth = Convert.ToUInt32(Scenario4ImageContainer.Width)
};
PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8, // WriteableBitmap uses BGRA format
BitmapAlphaMode.Straight,
transform,
ExifOrientationMode.IgnoreExifOrientation, // This sample ignores Exif orientation
ColorManagementMode.DoNotColorManage);
// An array containing the decoded image data, which could be modified before being displayed
byte[] sourcePixels = pixelData.DetachPixelData();
// Open a stream to copy the image contents to the WriteableBitmap's pixel buffer
using (Stream stream = Scenario4WriteableBitmap.PixelBuffer.AsStream())
{
for (int i = 0; i < columns * rows; i++)
{
await stream.WriteAsync(sourcePixels, 0, sourcePixels.Length);
}
}
}
// Redraw the WriteableBitmap
Scenario4WriteableBitmap.Invalidate();
Scenario4Image.Source = Scenario4WriteableBitmap;
Scenario4Image.Stretch = Stretch.None;
}
Thank you, Arkadiusz. Since Australian time goes slightly ahead of Europe,
I had an advantage and seen the code before you posted it. I downloaded
MSDN XAML images sample and it helped me a lot. I gave a +1 to you but someone apparently put -1, so it compensated each other. Don't be upset I get -1 so often, that I stopped paying attention on that :)
So I've managed to do tiling with Windows Universal Platform! On my Lumia 532 phone it works magnifique. I felt like re-inventing a wheel, because all this stuff must be handled by SDK, not by a third-party developer.
public static async Task<bool> setupTiledBackground(Panel panel, string tilePath)
{
Brush backgroundBrush = await createTiledBackground((int)panel.Width, (int)panel.Height, TilePath);
if (backgroundBrush == null) return false;
panel.Background = backgroundBrush;
return true;
}
private static async Task<Brush> createTiledBackground(int width, int height, string tilePath)
{
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///" + tilePath));
byte[] sourcePixels;
int tileWidth, tileHeight;
using (IRandomAccessStream inputStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
if (inputStream == null) return null;
BitmapDecoder tileDecoder = await BitmapDecoder.CreateAsync(inputStream);
if (tileDecoder == null) return null;
tileWidth = (int)tileDecoder.PixelWidth;
tileHeight = (int) tileDecoder.PixelHeight;
PixelDataProvider pixelData = await tileDecoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8, // WriteableBitmap uses BGRA format
BitmapAlphaMode.Straight,
new BitmapTransform(),
ExifOrientationMode.IgnoreExifOrientation,
ColorManagementMode.DoNotColorManage);
sourcePixels = pixelData.DetachPixelData();
// fileStream.Dispose();
}
WriteableBitmap backgroundBitmap = new WriteableBitmap(width, height);
int tileBmpWidth = tileWidth << 2;
int screenBmpWidth = width << 2;
int tileSize = tileBmpWidth * tileHeight;
int sourceOffset = 0;
using (Stream outputStream = backgroundBitmap.PixelBuffer.AsStream())
{
for (int bmpY=0; bmpY < height; bmpY++) {
for (int bmpX = 0; bmpX < screenBmpWidth; bmpX += tileBmpWidth)
await outputStream.WriteAsync(sourcePixels, sourceOffset, Math.Min(screenBmpWidth - bmpX, tileBmpWidth));
if ((sourceOffset += tileBmpWidth) >= tileSize)
sourceOffset -= tileSize;
}
}
ImageBrush backgroundBrush = new ImageBrush();
backgroundBrush.ImageSource = backgroundBitmap; // It's very easy now!
return backgroundBrush; // Finita la comédia!
}
Just one remark: if you do it on form start, you should not wait for it.
This doesn't work:
public MainPage()
{
this.InitializeComponent();
bool result = setupTiledBackground(contextPanel, TilePath).Result;
}
This works:
private Task<bool> backgroundImageTask;
public MainPage()
{
this.InitializeComponent();
backgroundImageTask = setupTiledBackground(contextPanel, TilePath);
}

How to make a simple screenshot method using LWJGL?

So basically I was messing about with LWJGL for a while now, and I came to a sudden stop with with annoyances surrounding glReadPixels().
And why it will only read from left-bottom -> top-right.
So I am here to answer my own question since I figured all this stuff out, And I am hoping my discoveries might be of some use to someone else.
As a side-note I am using:
glOrtho(0, WIDTH, 0 , HEIGHT, 1, -1);
So here it is my screen-capture code which can be implemented in any LWJGL application C:
//=========================getScreenImage==================================//
private void screenShot(){
//Creating an rbg array of total pixels
int[] pixels = new int[WIDTH * HEIGHT];
int bindex;
// allocate space for RBG pixels
ByteBuffer fb = ByteBuffer.allocateDirect(WIDTH * HEIGHT * 3);
// grab a copy of the current frame contents as RGB
glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, fb);
BufferedImage imageIn = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);
// convert RGB data in ByteBuffer to integer array
for (int i=0; i < pixels.length; i++) {
bindex = i * 3;
pixels[i] =
((fb.get(bindex) << 16)) +
((fb.get(bindex+1) << 8)) +
((fb.get(bindex+2) << 0));
}
//Allocate colored pixel to buffered Image
imageIn.setRGB(0, 0, WIDTH, HEIGHT, pixels, 0 , WIDTH);
//Creating the transformation direction (horizontal)
AffineTransform at = AffineTransform.getScaleInstance(1, -1);
at.translate(0, -imageIn.getHeight(null));
//Applying transformation
AffineTransformOp opRotated = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
BufferedImage imageOut = opRotated.filter(imageIn, null);
try {//Try to screate image, else show exception.
ImageIO.write(imageOut, format , fileLoc);
}
catch (Exception e) {
System.out.println("ScreenShot() exception: " +e);
}
}
I hope this has been useful.
For any questions or comments on the code, ask/suggest as you like. C:
Hugs,
Rose.
sorry for the late reply but this is for anybody still looking for a solution.
public static void saveScreenshot() throws Exception {
System.out.println("Saving screenshot!");
Rectangle screenRect = new Rectangle(Display.getX(), Display.getY(), Display.getWidth(), Display.getHeight());
BufferedImage capture = new Robot().createScreenCapture(screenRect);
ImageIO.write(capture, "png", new File("doc/saved/screenshot.png"));
}