Lock image (or picture) or Get image (or picture) from excel using EPPlus - export-to-excel

I'm using EPPlus for excel export. In that, I've locked image. Through code before insert some values to cells, I've unprotect sheet data or cells.
After unprotect, I've inserted values and locked those cells and then applied protection. For the cells which have data are locked. But the image has unlocked.
Now I'm having only two solution.
How to keep the image (or picture) has locked in sheet.
How to get the image (or picture) from excel and insert that image as embedded.
How to do that ? Here i've given my code.
// If worksheet has protection already, then need to unprotect
if (workSheet.Protection.IsProtected)
workSheet.Protection.IsProtected = false;
else
workSheet.Cells.Style.Locked = false;
workSheet.Cells[rowIndex, columnIndex].value="Test";
workSheet.Cells[rowIndex, columnIndex].Style.Locked=true;
// Protect the sheet after cells locked
workSheet.Protection.IsProtected = true;
workSheet.Protection.SetPassword(BasReportPassword);
workSheet.Protection.AllowSelectLockedCells = true;
workSheet.Protection.AllowSelectUnlockedCells = true;
excelPackage.Save();

For already protected sheet no need to give sheet as unprotected. so Leave the sheet as it as protected and make newly created cells as locked . Then it'll work. It doesn't follow as we do manually in the excel sheet.
Remove the following code. Then it'll work.
if (workSheet.Protection.IsProtected)
workSheet.Protection.IsProtected = false;
I've checked. Please try this.

Related

Aspose PDF .Net repeating same image multiple times in a table

I'm trying to add a table to a PDF. Each row will have an image in a column. There are 3 images which will repeat in the rows.
If I just directly add the image to table cell like below, performance is very poor. It may be cause each image is treated as a separate new one.
cell.Paragraphs.Add(new Image(imagePath + "on.png"));
The below article describes how to add images to resources and reuse it. But I'm not able to figure out how this should be applied to a table cell. To be precise I'm able to add Aspose.Pdf.Image to a cell but not Aspose.Pdf.XImage.
https://docs.aspose.com/display/pdfnet/Manipulate+Images#ManipulateImages-AddImagetoExistingPDFFile
You can try to reuse the same Image object.
Image img = new Image(imagePath + "on.png");
cell.Paragraphs.Add(img):
cell.Paragraphs.Add(img):

itext7 PdfButtonFormField setImage method does not work on a signed pdf

I am using itext7 java library as shown below to add PdfButtonFormField to an existing pdf :
String src = "sample.pdf";
String dest = "acro_sample_empty_fields.pdf";
PdfDocument pdf = new PdfDocument(new PdfReader(src), new PdfWriter(dest));
PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
PdfButtonFormField button = PdfFormField.createPushButton(pdf, new Rectangle(Integer.parseInt(control.xCord), Integer.parseInt(control.yCord),Integer.parseInt(control.width), Integer.parseInt(control.height)), control.name, control.value);
form.addField(button, page);
String resource = "sample.png";
button.setImage(resource);
After this i use the following code to fill the form like below :
String src = "1540982441_313554925_acro_sample_empty_fields_signedFinal.pdf";
String dest = "acro_sample_filled_fields.pdf";
PdfReader reader = new PdfReader(src);
File output = new File(dest);
OutputStream outputStream = new FileOutputStream(output);
PdfDocument document = new PdfDocument(reader,
new PdfWriter(outputStream),
new StampingProperties().useAppendMode());
PdfAcroForm form = PdfAcroForm.getAcroForm(document, true);
Map<String, PdfFormField> fields = form.getFormFields();
String resource = "sample_test.png";
((PdfButtonFormField)fields.get(control.name)).setImage(resource);
Everything works fine for a normal pdf. But if i digitally sign the created pdf and then try to fill it. then the image is not set properly.
For a normal pdf the image on the push button is changed as expected. But on the digitally signed pdf the image is not set.
I have tried looking for this on google but no luck yet. Any help will be appreciated. Thanks in advance.
I tested the code in this answer with the signed but unfilled PDF you shared. As you didn't share a sample image, though, I used one of my own.
A more precise observation
You say
Everything works fine for a normal pdf. But if i digitally sign the created pdf and then try to fill it. then the image is not set properly. For a normal pdf the image on the push button is changed as expected. But on the digitally signed pdf the image is not set.
This is not entirely true, the image is set but not all PDF viewers show it.
In detail: If you set the image in the signed PDF using your code, Adobe Reader indeed shows merely a grey box
but other PDF viewers, e.g. Foxit or Chrome's built-in viewer, do show the replacement image
Thus, the image is set for the digitally signed PDF, too. The actual problem is that Adobe Reader does not display it!
The cause
After some analysis and having followed some red herrings, the cause of the problem appears to be that if Adobe Reader displays a PDF with a changed AcroForm button appearance and
the PDF is not signed, then Adobe Reader simply uses the updated appearance stream; but if
the PDF is signed, then Adobe Reader tries to ignore the updated appearance stream and construct a new appearance from appearance characteristics information.
(Other PDF viewers, though, appear to always use the updated appearance stream.)
iText does create an appearance characteristics dictionary for the button (so Adobe Reader assumes it can ignore the updated appearance and can construct an new one based on this dictionary) but unfortunately does not add some button specific information to it, neither when constructing the button nor when changing the button. This in particular concerns the following two entries:
I
stream
(Optional; push-button fields only; shall be an indirect reference) A form XObject defining the widget annotation’s normal icon, which shall be displayed when it is not interacting with the user.
TP
integer
(Optional; push-button fields only) A code indicating where to position the text of the widget annotation’s caption relative to its icon:
0 No icon; caption only
1 No caption; icon only
2 Caption below the icon
3 Caption above the icon
4 Caption to the right of the icon
5 Caption to the left of the icon
6 Caption overlaid directly on the icon
Default value: 0.
(ISO 32000-2, Table 192 — Entries in an appearance characteristics dictionary)
As iText does not supply the TP value, the Default value kicks in and Adobe Reader creates a button appearance with "No icon; caption only". As no caption is defined, the result is a grey box.
A work-around
The most simple work-around is to remove the whole appearance characteristics dictionary during image update, i.e. replace
((PdfButtonFormField)fields.get(control.name)).setImage(resource);
by
PdfButtonFormField button = (PdfButtonFormField)fields.get(control.name);
button.setImage(resource);
if (button.getPdfObject().containsKey(PdfName.MK)) {
button.setModified();
button.getPdfObject().remove(PdfName.MK);
}
(SetButtonImage helper method setLikeGautamAnandImproved)
Now Adobe Reader does not find any appearance characteristics and, therefore, cannot ignore the updated appearance stream.
A fix
Alternatively we can add the missing appearance characteristics entries, e.g. like this:
PdfButtonFormField button = (PdfButtonFormField)fields.get(control.name);
button.setImage(resource);
PdfWidgetAnnotation widget = button.getWidgets().get(0);
PdfDictionary characteristics = widget.getAppearanceCharacteristics();
if (characteristics != null) {
characteristics.setModified();
characteristics.put(PdfName.I, widget.getNormalAppearanceObject());
characteristics.put(PdfName.TP, new PdfNumber(1));
}
(SetButtonImage helper method setLikeGautamAnandImproved2)
The result looks slightly different, though:
As you see, there is a small frame around the image. Most likely you can make it vanish by setting other characteristics accordingly.

How to overlay TWO images and save them into AN image? (Flash CS5)

I am a total noob with Flash. And i am no programmer. Just good with photoshop (image designing).
Here is my problem. I found a simple drawing application and modified it, only the interface, not the codings.
It provides a 'save button' that enables to save the drawing (drawn on MovieClip) into diskdrive. And then i modified it, put another layer on top of the MovieClip a Graphic. But then when i try to save it, it only saves the MovieClip as a .png image. What i want is that it saves the MovieClip along with the Graphic layered on top of it into one .png image. How can i do that?
Maybe it'll be more helpful if I provide the code to the 'save button'?
** /* Save */
private function export():void
{
var bmd:BitmapData = new BitmapData(600, 290);
bmd.draw(board);
var ba:ByteArray = PNGEncoder.encode(bmd);
private function completeHandler(event:Event):void {
var loader:URLLoader = URLLoader(event.target);
trace("completeHandler: " + loader.data);
}
private function saveSuccessful(e:Event):void
{
saveDialog = new SaveDialog();
addChild(saveDialog);
saveDialog.closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeSaveDialog);
}
private function closeSaveDialog(e:MouseEvent):void
{
removeChild(saveDialog);
}
private function save(e:MouseEvent):void
{
export();
}**
EDIT: i have put 'bmd.draw(topLayer);' under the first draw() call but then when i published a preview it says "Access of undefined property topLayer". i checked its property first it mentions this 'Instance of: topLayer' and it is a Graphic.
Check the codes. There should be a construction fileReference.save(someOtherName) somewhere, probably with different name for fileReference, but it will be declared nearby as FileReference=new FileReference(). Then, track that someOtherName above, it should be an output of PNGEncoder.encode() of yet another variable, which should be of type BitmapData. Find out what is drawn on that bitmap data, there will be a line bitmapData.draw(someMovieClip). Find out if that someMovieClip is only the layer that's drawn upon in your program. You can add a similar line right after that one to draw your shape (you should have its name so you could reference it in code), this will draw your Graphic over the thing that you draw.
In case the entire graphics drawn by you can be fit within a single screen, just take a screenshot of your application in progress, load it up into Photoshop and have fun with your graphics be correctly on top of whatever it saves. Or, use an existing saved image as a background layer, place a screenshot as foreground, clear the areas that are not your graphics and have some more fun.
EDIT: Okay, there it is: You have export() function (which is incomplete in your copypasting, BTW), with all the relevant part I've mentioned. There is a draw() call, a PNGEncoder.encode() call, and a BitmapData object. You should add another line of code after the first draw() call with something like this:
bmd.draw(yourGraphic);
YourGraphic is the name of the graphic you have manually added above the MovieClip, the one you can edit in its properties on stage. Should do.
REPLY: i have put bmd.draw(topLayer); under the first draw() call but then when i published a preview it says "Access of undefined property topLayer". i checked its property first it mentions this 'Instance of: topLayer' and it is a Graphic.

DynamicPDF image quality loss

We are using a product called DynamicPDF to generate PDF's on the fly from dynamic data from a database. Their documentation says that their software leaves the image bytes intact and doesn't make any changes. Despite this, we have observed that the images we add seem to have quality loss on the resulting PDF output (at least that's how they look). So my question is what do I need to do with the DynamicPDF API to ensure that the image quality output is equal or close to what I put in?
We are using Version 5.1.2 Build 13650, below is the code that we use to add the image.
private void plcImageMain_LaidOut(object sender, PlaceHolderLaidOutEventArgs e)
{
if (e.LayoutWriter.RecordSets.Current.HasData)
{
string productId = e.LayoutWriter.RecordSets.Current["ProductId"].ToString();
string imgUrl = base.SetImageUrlParams(e.LayoutWriter.RecordSets.Current["ImageUrl"] as string, e.ContentArea.Width, e.ContentArea.Height);
System.Drawing.Bitmap bm = base.GetBitmap(imgUrl);
ceTe.DynamicPDF.PageElements.Image img = new ceTe.DynamicPDF.PageElements.Image(bm, 0, 0);
img.Height = e.ContentArea.Height;
img.Width = e.ContentArea.Width;
e.ContentArea.Add(img);
}
}
/// <summary>
/// Gets a bitmap from the requested image url
/// </summary>
/// <param name="imgCtrl"></param>
/// <param name="imgUrl"></param>
protected System.Drawing.Bitmap GetBitmap(string imgUrl)
{
// TODO: Add some validation to ensure the url is an image.
System.Net.WebRequest httpRequest = System.Net.HttpWebRequest.Create(imgUrl);
using (System.Net.HttpWebResponse httpResponse = httpRequest.GetResponse() as System.Net.HttpWebResponse)
using (Stream imgStream = httpResponse.GetResponseStream())
{
System.Drawing.Bitmap bm = System.Drawing.Bitmap.FromStream(imgStream) as System.Drawing.Bitmap;
return bm;
}
}
[Edit]
Here is the before and after screenshot.
[Edit]
Code using GetImage (why so slow?)
protected ceTe.DynamicPDF.Imaging.ImageData GetImageData(string imgUrl)
{
ImageData imgData = null;
using (System.Net.WebClient wc = new System.Net.WebClient())
{
imgData = ImageData.GetImage(wc.DownloadData(imgUrl));
}
return imgData;
}
GetImageData ("http://s7d2.scene7.com/is/image/SwissArmy/cm_vm_53900E--111mm_sol_front_a?fmt=jpeg&wid=400&hei=640");
All right, this looks like poor effort at resizing but it could just as well be your Acrobat reader doing it on screen, with the actual data being perfectly fine.
You should be able to select an image by clicking it in Reader (so it's highlighted blue) and then copy and paste it to an image editing program of your choice. That way, you should get the resource in original solution no matter what it's scaled down to.
There are also tools to extract images and other resources from PDFs, but I don't know one I can recommend offhand.
In regards to the DynamicPDF product, there is not any resizing or resampling done to the image as it is added to the PDF document. Pekka is actually right on with this. It is the reader that is visually representing the image with differing clarity (at different zoom levels).
If you are able to pull the image out of the PDF (as Pekka recommends above) you will see the image data is completely original and not modified.
One additional thing you can do to demonstrate this would be to take your original image, right click on it and select "Convert To Adobe PDF" (requires full Acrobat Pro). In that newly created PDF you would also visually see the same results.
One final thing worth noting is just a smalll inefficiency in the code you displayed above. Right now you are pulling the image content as a Stream, creating a bitmap out of that Stream object and then using that bitmap to create the DynamicPDF Image object. The recommended way to accomplish this would be to take the Stream object of the image that you are pulling from the URL, pass this into the DynamicPDF's ImageData Static method "GetImage". This GetImage method will return the ImageData object. Then use that ImageData to create your DynamicPDF Image object out of.
There are two clear advantages to loading the image this way. First is that you do not have the overhead involved with the System.Drawing.Bitmap object needing to separately process the image content (so in theory the app would run faster without this). And the second advantage is that the image content is added to the PDF in whatever native compression that it was originally in. As in the case of JPEG images, using the image’s native compression as opposed to the bitmap’s compression will result in a smaller output PDF file size. None of this will have any influence on the image quality of the output PDF but it could affect the efficiency and output PDF file size.
You were both right that it was Acrobat that was causing the fuzzy display. There is a setting in preferences called resolution, instead of using the System dpi setting by default Acrobat decided to use a custom dpi setting of 110 (I have no idea why!?!?). After setting it to system (in my case 96dpi) the images were crystal clear.

Dynamically change an image in a Crystal Report at runtime

I'm using the Crystal Reports included with VisualStudio 2005. I would like to change the image that is displayed on the report at runtime ideally by building a path to the image file and then have that image displayed on the report.
Has anyone been able to accomplish this with this version of Crystal Reports?
At work we do this by pushing the image(s) into the report as fields of a datatable. It's not pretty, but it gets the job done. Of course, this solution requires that you push data into the reports via a DataSet. I've always felt this was a hack at best. I really wish that image parameters were a possibility with CR.
Edit: It's worth noting, if you are binding your crystal report to plain old objects you want to expose a byte[] property for the report to treat that as an image.
I finally reached a solution using the byte[] tip posted here by Josh.
This solution applies if you are using a plain old C# Object to populate your Crystal Reports (see http://www.aspfree.com/c/a/C-Sharp/Crystal-Reports-for-Visual-Studio-2005-in-CSharp/ for info on this approach).
In your C# class, insert the following code:
private static byte[] m_Bitmap = null;
public byte[] Bitmap
{
get
{
FileStream fs = new FileStream(bitmapPath, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
int length = (int)br.BaseStream.Length;
m_Bitmap = new byte[length];
m_Bitmap = br.ReadBytes(length);
br.Close();
fs.Close();
return m_Bitmap;
}
}
Now, update your C# Object Mapping in CR using the "Verify Database" option. You should then see the Bitmap property as a CR field. Just drag it onto the form. It will be of type IBlobFieldObject. When you run, you should see your image.
[I have since found a solution using a byte array via a C# Object property - see separate Answer. Leaving this answer here for reference...]
Here's what I have seen suggested (but I tried and failed in both C#-2005 and C#-2008).
Choose a directory and place a BMP there (e.g., "C:\Temp\image.bmp").
From the CR-Designer a) Right-click->Insert->OLE Object... b) Select "Create from File" c) Check the "Link" checkbox d) Browse and pick the bmp defined in step 1 e) Click OK f) Place the image on the form.
Overwrite/update the image at runtime in your C# code. In theory, since you inserted a Link to an image file, it will be updated when the form is refreshed.
I had no luck with this approach. The image appears when I first design the form (step 2). But at runtime, the image does not update for me. From this point forward, things get really odd. It seems that CR caches some sort of image that just won't go away. I can delete the OLE object link in CR-Designer, but if I recreate it, I always get a black box the same size as the original image (even if I change the size of image.bmp).
You can also use a conditional formula to set an image's location. See Crystal Reports: Dynamic Images.
Try using a combination of using a parameter containing the path of the image and the tutorial on this page: http://www.idautomation.com/crystal/streaming_crystal.html
Then in step #8, use the parameter instead of a hard-coded path.
Another option that I've found useful is inserting the pictures you would like to use. Position the graphic accordingly, then right-click the graphic and go to Format Graphic > Common. Check the Suppress box, then click the formula button, shown as x-2. Once in the formula window, simply add the code for determining whether the graphic should be suppressed or not.
In my case, I was building one invoice template for multiple entities. In the formula window, I simply wrote COMPANY <> 1100 which meant that every time the invoice was run for a company other than 1100, the 1100 graphic would be suppressed.
Hopefully this makes life easier...
The current version of Crystal Reports (for Visual Studio 2012+) that I use with Visual Studio 2015 supports this function. Follow the following steps:
Insert a picture into your report. This will serve as your
placeholder.'
Right click your picture and choose Format Object
Select the Picture tab and the press the formula button
A formula window will open. Enter a formula that will find your pictures as links.
if({#isDonor}="1")
then "http://www.ny.org/images/aaf/picture1.jpg"
else "http://www.ny.org/images/aaf/picture2.jpg"
And you're done!
Just like Josh said.. You will have to push the image with a dataset. Or, put the image into a database table once and pull it in many times with a subreport.

Resources