I am creating an PDF from HTML using ABC PDF 8.0, it works well on my local end but generate a blank page on IIS, I already down grade IE, and provide the all permission to folder. When I tried to generate the PDF through any external link like Google.com it works perfectly. more over my link is accessible and there is no error on the page. please find below the code for your reference.
var url="test.com"
if (XSettings.InstallLicense(abcPDFkey))
{
using (Doc theDoc = new Doc())
{
//apply a rotation transform
double w = theDoc.MediaBox.Width;
double h = theDoc.MediaBox.Height;
double l = theDoc.MediaBox.Left;
double b = theDoc.MediaBox.Bottom;
theDoc.Transform.Rotate(90, l, b);
theDoc.Transform.Translate(w, 0);
// To fix time out
theDoc.HtmlOptions.RetryCount = 1;
theDoc.HtmlOptions.Timeout = 25000;
// rotate our rectangle
theDoc.Rect.Width = h;
theDoc.Rect.Height = w;
theDoc.HtmlOptions.Engine = EngineType.Gecko;
theDoc.HtmlOptions.ImageQuality = 60;
int theID;
theID = theDoc.AddImageUrl(url);
while (true)
{
theDoc.FrameRect();
if (!theDoc.Chainable(theID))
break;
theDoc.Page = theDoc.AddPage();
theID = theDoc.AddImageToChain(theID);
int NewtheID = theDoc.GetInfoInt(theDoc.Root, "Pages");
theDoc.SetInfo(NewtheID, "/Rotate", "90");
}
for (int i = 1; i <= theDoc.PageCount; i++)
{
theDoc.PageNumber = i;
theDoc.Flatten();
}
foreach (IndirectObject io in theDoc.ObjectSoup)
{
if (io is PixMap)
{
PixMap pm = (PixMap)io;
pm.Realize(); // eliminate indexed color images
pm.Resize(pm.Width / 6, pm.Height / 6);
}
}
theDoc.Save(System.Web.HttpContext.Current.Server.MapPath("PDFFileName"));
theDoc.Clear();
}
Please help, thanks
Ok, I figured out what was the issue.
First of all I define the relative path for all my Images, and secondly Our server have internal IP, I define the URL for internal IP instead of public domain. that fix my issue..
cheers !!
Related
I need to do that in my program. I have to do it in two ways:
1.) by my own, with the following code:`
private Image convertToGrayScale(Image image) {
WritableImage result = new WritableImage((int) image.getWidth(), (int)
image.getHeight());
PixelReader preader = image.getPixelReader();
PixelWriter pwriter = result.getPixelWriter();
for (int i = 0; i < result.getWidth(); i++) {
for (int j = 0; j < result.getHeight(); j++) {
Color c = preader.getColor(i, j);
double red = (c.getRed() * 0.299);
double green = (c.getGreen() * 0.587);
double blue = (c.getBlue() * 0.114);
double sum = c.getRed() + c.getBlue() + c.getGreen();
pwriter.setColor(i , j, new Color(sum, sum, sum, 1.0));
}
}
return result;
}
2.) with the help of the openCV library, with the following code (it was copied almost perfectly from their site) :
public WritableImage loadAndConvert() throws Exception {
//Loading the OpenCV core library
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
String input = "C:/Users/Dan Ivgy/eclipse-workspace/LuckyBride/sample/20180402_170204.jpg";
//Reading the image
Mat src = Imgcodecs.imread(input);
//Creating the empty destination matrix
Mat dst = new Mat();
//Converting the image to gray scale and saving it in the dst matrix
Imgproc.cvtColor(src, dst, Imgproc.COLOR_RGB2GRAY);
// Imgcodecs.imwrite("C:/opencv/GeeksforGeeks.jpg", dst);
//Extracting data from the transformed image (dst)
byte[] data1 = new byte[dst.rows() * dst.cols() * (int)(dst.elemSize())];
dst.get(0, 0, data1);
//Creating Buffered image using the data
BufferedImage bufImage = new BufferedImage(dst.cols(),dst.rows(),
BufferedImage.TYPE_BYTE_GRAY);
//Setting the data elements to the image
bufImage.getRaster().setDataElements(0, 0, dst.cols(), dst.rows(), data1);
//Creating a WritableImage
WritableImage writableImage = SwingFXUtils.toFXImage(bufImage, null);
System.out.println("Converted to Grayscale");
return writableImage;
}
In both cases, the problem was that i have'nt got a "greyscale" output, just somthing different (and before you
asked: yeas, i have tried to to do it on several pictures, not only one)
Here's the input picture and the output picture:
Well, as you can see, this is Not a greyscale! maybe a sunset-scale..
I'd really appraciate any help, Thank you :)
(espcially if there's something faster out there since those solutions rather takes a while to run)
If someone knows, why there is not some built in option in javaFX as there is a lot of sophisticated imageview effects and this one is so simple and so prevalent.
UPDATE:
i found a website that do somthing similar to ehat i did - and somehow i got a different output! i don't get it
here's the website.
and here's the output from my computer:
my output
UPDATE#2: as #matt correctly asked, here's the code that use this method:
ImageIO.write(SwingFXUtils
.fromFXImage
(convertToGrayScale(new Image(getClass().getResource("1_CNc4RxV85YgthtvZh2xO5Q.jpeg").toExternalForm()) ), null), "jpg", file);
the original target was to show the image to rhe user, and the problem was there, so i changed the code to this one which save the image so i could isolate the problem more easly..
Ok guys, after some research, and endless number of attememts i got what i need
to solve the problem ill show my solution here and come to a coclude of my insights about this issue..
first, ill give the the disticntion between "SAVING the file" and "Setting the file in the ImageView.
when we want just to show it in image view, i have'ne expereinced any problem using almost every solution suggested here. the most simple, short and sweet (in my opinion) is the following one:
private Image convertToGrayScale(Image image) {
WritableImage result = new WritableImage((int) image.getWidth(), (int) image.getHeight());
PixelReader preader = image.getPixelReader();
PixelWriter pwriter = result.getPixelWriter();
for (int i = 0; i < result.getWidth(); i++)
for (int j = 0; j < result.getHeight(); j++)
pwriter.setColor(i , j, preader.getColor(i, j).grayscale());
return result;
}
(for convinience, i ignored exception handling)
it works fine when i use it along when i use it along with the following code:
Image img1 = convertToGrayScale(new Image(filepath);
imageView.setImage(img1);
about SAVING this output image, after some research and using #trashgold 's references, and this important one :
i got my solution as the following:
private void saveBadImage(BufferedImage originalImage, File dest) throws IOException
{
// use the following line if you want the first parameter to be a filepath to src image instead of Image itself
//BufferedImage originalImage = ImageIO.read(file);
// jpg needs BufferedImage.TYPE_INT_RGB
// png needs BufferedImage.TYPE_INT_ARGB
// create a blank, RGB, same width and height
BufferedImage newBufferedImage = new BufferedImage(
originalImage.getWidth(),
originalImage.getHeight(),
BufferedImage.TYPE_INT_RGB);
// draw a white background and puts the originalImage on it.
newBufferedImage.createGraphics().drawImage(originalImage,0,0,null);
// save an image
ImageIO.write(newBufferedImage, "jpg", dest);
}
and, i use it with the following code:
Image img1 = convertToGrayScale(new Image(filepath));
BufferedImage img2 = new BufferedImage((int) img1.getWidth(), (int) img1.getHeight(), BufferedImage.TYPE_INT_ARGB);
saveBadImage(img2, file);
and, it works perfectly!
Thank you all guys, and i hope my insights will help to some people
I decided to work in awt, then create a javafx image.
public class App extends Application {
#Override
public void start(Stage stage) {
WritableImage gray = null;
try {
BufferedImage awtImage = ImageIO.read(new URL("https://i.stack.imgur.com/ysIrl.jpg"));
gray = new WritableImage(awtImage.getWidth(), awtImage.getHeight());
BufferedImage img2 = new BufferedImage(awtImage.getWidth(), awtImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
for(int i = 0; i<awtImage.getWidth(); i++){
for(int j = 0; j<awtImage.getHeight(); j++){
int c = awtImage.getRGB(i, j);
int r = (c>>16)&255;
int g = (c>>8)&255;
int b = (c)&255;
int s = (int)(r*0.299 + g*0.587 + b*0.114);
int gr = (255<<24) + (s<<16) + (s<<8) + s;
img2.setRGB(i, j, gr);
}
}
gray = SwingFXUtils.toFXImage(img2, gray);
} catch (IOException e) {
e.printStackTrace();
}
ImageView view = new ImageView(gray);
ScrollPane pane = new ScrollPane(view);
Scene scene = new Scene(new StackPane(pane), 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Both methods work for me, so I'm not sure if this helps you. I can save the result too.
System.out.println("saving " +
ImageIO.write(img2, "PNG", new File("tested.png")) );
If you're using oracles jdk, I think you can save JPEG. I am using OpenJDK which doesn't seem to be able to write JPEG.
So for some project i'm working with Xamarin.Forms.
Since one area is just unbearably slow with Xamarin.Forms i've used a CustomRenderer to solve one particular area where a list is involved.
After getting back to the project and upgrading packages, i've suddenly got the weirdest bug.
I am setting "1234" to an EditText, and the EditText.Text Property is suddenly "49505152" - the string is converted to its ascii equivalent.
Is this a known issue? Does anyone know how to fix it?
The cause of the issue was that my EditText had an InputFilter applied and that after updating a package suddenly another code path of FilterFormatted was executed.
public ICharSequence FilterFormatted(ICharSequence source, int start, int end, ISpanned dest, int dstart, int dend)
{
var startSection = dest.SubSequenceFormatted(0, dstart);
var insert = source.SubSequenceFormatted(start, end);
var endSection = dest.SubSequenceFormatted(dstart, dest.Length());
var merged = $"{startSection}{insert}{endSection}";
if (ValidationRegex.IsMatch(merged) && InputRangeCheck(merged, CultureInfo.InvariantCulture))
{
StringBuilder sb = new StringBuilder(end - start);
for (int i = start; i < end; i++)
{
char c = source.CharAt(i);
sb.Append(c);
}
if (source is ISpanned) {
SpannableString sp = new SpannableString(sb);
TextUtils.CopySpansFrom((ISpanned)source, start, sb.Length(), null, sp, 0);
return sp;
} else {
// AFTER UPDATE THIS PATH WAS ENTERED UNLIKE BEFORE
return sb;
}
}
else
{
return new SpannableString(string.Empty);
}
}
We have ASP.NET app in which, I am trying to merge two PDF files and we are currently using BCL easyPDF7 library. I am trying to merge new file at specific location or page (for example after 3rd page in main document) But I found that Merge in this library simply appends the file in the end.
We have decided to go for new tool PDF4NET and I observed from the sample codes of PDF4NET that they also provide Merge functionality which appends the document in the end.
Is there any way we can achieve this ? (either through PDF4NET or BCL easyPDF7 ) Please share your views.
I've used iTextSharp before to do this and basically create a new output pdf and then read in the new documents and loop through the pages adding the pages to the new output document. This will even maintain pagesize and orientation information for each page.
Here is the code that adds the pdf to the output one:
int pc = pdfReader.NumberOfPages;
int p, rotation;
Rectangle box;
PdfImportedPage page;
for (p = 0; p < pc; p++) {
pageNo++;
page = pdfWriter.GetImportedPage(pdfReader, p + 1);
rotation = pdfReader.GetPageRotation(p + 1);
box = pdfReader.GetPageSizeWithRotation(p + 1);
outputDoc.SetPageSize(box);
outputDoc.NewPage();
if ((rotation == 90) || (rotation == 270)) {
pdfContentByte.AddTemplate(page, 0, -1.0f, 1.0f, 0, 0, box.Height);
} else {
pdfContentByte.AddTemplate(page, 1.0f, 0, 0, 1.0f, 0, 0);
}
}
pdfReader.Close();
In this example pdfReader is an instance of PdfReader class referencing the source pdf to add. This can be by either file, stream or byte array. pdfWriter is a new instance of PdfWriter class that is the output content.
I know it isn't using PDF4NET or BCL easyPDF7 but hopefully it will help.
I got it working by extracting pages and creating a new file. I extracted the pages from main file upto index which is page number at which I want to insert my second file.
Hope it helps who are dealing with PDF4NET and want merge file at specific page number.
private string MergeFiles(string mainfile, string attachment, string path, int index)
{
var newFile = #"C:\Test\PDF\NewInsertedAt2.pdf";
int mainFilePages, attachFilePages, i, j, k;
PDFFile mainFile = PDFFile.FromFile(mainfile);
PDFFile attachFile = PDFFile.FromFile(attachment);
PDFImportedPage ip = null;
PDFDocument doc = new PDFDocument();
mainFilePages = mainFile.PagesCount;
attachFilePages = attachFile.PagesCount;
for (i = 0; i < index; i++)
{
ip = mainFile.ExtractPage(i);
doc.Pages.Add(ip);
}
for (j = 0; j < attachFilePages; j++)
{
ip = attachFile.ExtractPage(j);
doc.Pages.Add(ip);
}
for (k = i; k < mainFilePages; k++)
{
ip = mainFile.ExtractPage(k);
doc.Pages.Add(ip);
}
doc.Save(newFile);
mainFile.Close();
attachFile.Close();
return newFile;
}
I want to check if an IP address is in a certain range, matching by "*" only. For example, "202.121.189.8" is in "202.121.189.*".
The scenario is that I have a list of banned IPs, some of them contains "*", so I wrote a function, it works fine so far:
static bool IsInRange(string ip, List<string> ipList)
{
if (ipList.Contains(ip))
{
return true;
}
var ipSets = ip.Split('.');
foreach (var item in ipList)
{
var itemSets = item.Split('.');
for (int i = 0; i < 4; i++)
{
if (itemSets[i] == "*")
{
bool isMatch = true;
for (int j = 0; j < i; j++)
{
if (ipSets[i - j - 1] != itemSets[i - j - 1])
{
isMatch = false;
}
}
if (isMatch)
{
return true;
}
}
}
}
return false;
}
Test code:
string ip = "202.121.189.8";
List<string> ipList = new List<string>() { "202.121.168.25", "202.121.189.*" };
Console.WriteLine(IsInRange(ip, ipList));
But I think what i wrote is very stupid, and I want to optimize it, does anyone have an idea how to simplify this function? not to use so many "for....if...".
A good idea would be to represent the banned subnets in a form of a pair: mask + base address. So your check will look like that:
banned = (ip & mask == baseaddress & mask);
For 11.22.33.* the base address will be 11*0x1000000 + 22*0x10000 + 33*0x100, mask will be 0xffffff00.
For single address 55.44.33.22 the address will be 55*0x1000000 + 44*0x10000 * 33*0x100 + 22, mask will be 0xffffffff.
You'll need to convert the address to a 32-bit int as a separate procedure.
After that all, your code will look like that:
int numip = ip2int(ip);
bool isIpBanned = banList.Any(item =>
numip & item.mask == item.baseaddress & item.mask);
By the way, this way you'll be able to represent even bans on smaller subsets.
int ip2int(string ip) // error checking omitted
{
var parts = ip.Split('.');
int result = 0;
foreach (var p in parts)
result = result * 0x100 + int.Parse(p);
}
class BanItem { public int baseaddres; public int mask; }
BanItem ip2banItem(string ip)
{
BanItem bi = new BanItem() { baseaddres = 0, mask = 0 };
var parts = ip.Split('.');
foreach (var p in parts)
{
bi.baseaddress *= 0x100;
bi.mask *= 0x100;
if (p != "*")
{
bi.mask += 0xff;
bi.baseaddress += int.Parse(p);
}
}
return bi;
}
banList = banIps.Select(ip2banItem).ToList();
I think you should keep a separate list for IP with * and those without asterick.
say IpList1 contains IP's without *
and
IpList2 --those contain * ..actually what we will be storing is the part before .* in this list. for e.g. 202.121.189.* would be stored as 202.121.189 only..
Thus for a given IP addrerss you just need to check for that IP address in IpList1,if it is not found over there then
for each Ip in IPList 2 you need to check whether it is a substring of input IP or not.
Thus no requirement of complex for and if loops.
Written In Java (Untested):
static boolean IsInRange(String ip, Vector<String> ipList) {
int indexOfStar = 0;
for (int i=0; i<ipList.size(); i++) {
if (ipList.contains("*")) {
indexOfStar = ipList.indexOf("*");
if ((ip.substring(0, indexOfStar)).equals(ipList.get(i).substring(0, indexOfStar))) {
return true;
}
}
}
return false;
}
I would use a space filling curve like in the xkcd comic: http://xkcd.com/195/. It's the function H(x,y) = (H(x),H(y)) and it reduces the 2 dimension to 1 dimension. It would also show that you are a real b*** coder.
i have a function that pulls URLs from various web resources. needless to say some are full valid URLS and some are relative as per the HTML of the page. below is my asp.net/ c# logic i derived for examining the URL and then generate a full usable URL from whats pulled from the site...
I have have not looked at this code in some time but i remember it was working well some months ago and now it needed many tweaks to get running - especially with relative paths and the regeneration of a FULL url from various relative variations.
is there a simpler way or method to accomplish this seemingly routing boilerplate task than what i have here?
NOTE:
origianlurl is the full url of the first searched page, and relativeUrl is a url found within the searched page (it can be a full www.site.com or a /contactus.html)
private string ResolveRelativePaths(string relativeUrl, string originatingUrl)
{
if (relativeUrl.StartsWith("http") || relativeUrl.StartsWith("www"))
return relativeUrl;
if (relativeUrl.StartsWith("/"))
{
//get main url something.com
Uri myURI = new Uri(originatingUrl);
//add the relative page to the end
return myURI.Host + relativeUrl;
}
string resolvedUrl = String.Empty;
string[] relativeUrlArray = relativeUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
string[] originatingUrlElements = originatingUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
int indexOfFirstNonRelativePathElement = 0;
for (int i = 0; i <= relativeUrlArray.Length - 1; i++)
{
if (relativeUrlArray[i] != "..")
{
indexOfFirstNonRelativePathElement = i;
break;
}
}
int countOfOriginatingUrlElementsToUse = originatingUrlElements.Length - indexOfFirstNonRelativePathElement - 1;
//for (int i = 0; i <= countOfOriginatingUrlElementsToUse - 1; i++)
for (int i = 0; i <= countOfOriginatingUrlElementsToUse ; i++)
{
if (originatingUrlElements[i] == "http:" || originatingUrlElements[i] == "https:")
resolvedUrl += originatingUrlElements[i] + "//";
else
resolvedUrl += originatingUrlElements[i] + "/";
}
for (int i = 0; i <= relativeUrlArray.Length - 1; i++)
{
if (i >= indexOfFirstNonRelativePathElement)
{
resolvedUrl += relativeUrlArray[i];
if (i < relativeUrlArray.Length - 1)
resolvedUrl += "/";
}
}
return resolvedUrl;
}
The Uri class has a constructor that you can use for that exactly. Given a base uri, which is your originatingUrl and a string (the relative part) it generates the full url. As far as I can see there is not a single thing in your method that cannot be done using the Uri class (maybe a few instances). My guess is that you could rewrite it to 5-10 LOC.