I am writing an application for my parent's photo booth business.
They upload all the event pictures to different Flickr photosets on their account, and on the website they have an albums page with a collection of all their events so that people from the events can go and see all their photo strips, as well as each individual picture and then download them for themselves.
Most of their traffic is from mobile devices (my brother wrote the website specifically to fit mobile device screens as well as normal computer screens just as well); however, downloading and sharing the images is easier through an app (thanks to Apple's iOS 6 UIActivityViewController and UICollectionView).
So I'm writing the app that makes it easier to view and share the pictures. I have most of it done and working great! However, it currently only supports iOS 6 and I'm trying to include iOS 5. It only supports iOS 6 because I am using a UICollectionView to display the pictures from events. However, since iOS 5 does not include collection views I use a web view of our albums web page which displays all images.
When you select an image, you can choose a size of the image to view. When you pick a size, it opens a new tab, that includes the image and two links. One to download the image, and one to close the tab. The two links are within an unordered list and each link is its own list item.
This is the link to download the image:
Download Image
And the closing tab link has a tag of:
<a href="javascript:window.close();">
I've seen that you can use the webView's delegate method shouldStartLoadWithRequest: and then:
if ([[[request URL] absoluteString] hasPrefix:#"/downloadImage.php"]) {
UIImageWriteToSavedPhotosAlbum(imageToBeSaved, nil, nil, nil);
return NO;
} else if ([[[request URL] absoluteString] hasPrefix:#"javascript"]) {
[webView goBack];
return NO;
} else { return YES; }
Which would make it do those functions when the links are clicked...right?
These do not work though. And I'm not sure how to make them work.
I am searching for the correct way to use this method, or some alternative method, if possible, to use Objective-C to do the equivalent of what the html normally does.
I figured out a way to do basically what I wanted. Rather than let the webView open a new page when you selected an image size. I set the size links to just download the image right there using this code:
// for links thats contain the displayImage.php do not allow user interaction
if ([[[request URL] absoluteString] hasPrefix:#"http://www.remembermephotobooths.com/displayImage.php?link="]) {
//scan through the link url get the image link so that I can download it
NSMutableArray *substring = [NSMutableArray new];
NSScanner *scanner = [NSScanner scannerWithString:[[request URL] absoluteString]];
[scanner scanUpToString:#"http://farm9" intoString:nil]; // Scan all characters after and including http://farm9 because all download links begin with http://farm9
while(![scanner isAtEnd]) {
NSString *string = nil;
[scanner scanString:#"&title=" intoString:nil]; // Scan up to &title
if([scanner scanUpToString:#"&" intoString:&string]) {
[substring addObject:string];
}
[scanner scanUpToString:#".jpg" intoString:nil]; // Scan all characters up to and including .jpg because all images are jpegs
}
// save image to photo library
UIImageWriteToSavedPhotosAlbum([UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:substring[0]]]], nil, nil, nil);
// let the user know the image was saved
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
[hud setMode:MBProgressHUDModeText];
hud.labelText = #"Saved Image!";
[hud setMinShowTime:1.5];
[MBProgressHUD hideHUDForView:self.view animated:YES];
[substring release];
return NO; //this is what disables the links usual code and has it run my code instead
}
else { //all other links are enabled
return YES;
}
Related
For my project I need to copy image (not url, image name. Only data for ability, for example, to paste it to "Microsoft Paint") from page to clipboard by Chrome console.
I tried this:
copy(document.getElementById('someimage'));
but it returns nothing... It only works with text.
If you don't know, then how to download this image by chrome console?
OR
How to make screenshot of the page and copy or download it using Chrome console?
P.s. I can't use any js libraries.
I have explored few things in chrome dev tools
https://homeguides.sfgate.com/stop-air-flow-ceiling-air-diffuser-28867.html - This is the website I am using it for reference.
In Chrome console try the following command
imageurl= document.getElementsByTagName('img')[0].currentSrc;
copy (imageurl);
Note: Here you can change the img [1] array if you want to get different images
Then if you press ctrl + v in your keyboard you could see the image url with https. Please see the above screenshot.
You can perform the ctrl+ v on your new tab to get the image loaded.
or You can try the following method.
Right click the image and click inspect element
You could see some image url. Copy that URL
Open new Tab and paste the URL
If you right click on it you can see "Save Images" option.
Hope it will help you in someway.
As you mentioned you are using Selenium, here's how to save an image with Selenium:
You need to get the image's URL, load it (using ImageIO in this example) and save it. For example, in Java you would do something like this:
try {
driver = new ChromeDriver();
driver.get("http://...");
WebElement img = driver.findElement(By.cssSelector("#selector"));
BufferedImage buffer = ImageIO.read(new URL(img.getAttribute("src")));
ImageIO.write(buffer, "png", new File("image.png"));
} catch (Exception e) {
e.printStackTrace();
} finally {
driver.close();
}
If you want to copy it directly, your class needs to implement java.awt.datatransfer.ClipboardOwner and then you would do something like this:
try {
driver = new ChromeDriver();
driver.get("http://...");
WebElement img = driver.findElement(By.cssSelector("#selector"));
TransferableImage transferable = new TransferableImage(ImageIO.read(new URL(img.getAttribute("src"))));
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(transferable, this );
} catch (Exception e) {
e.printStackTrace();
} finally {
driver.close();
}
Regarding your other questions, here's how to take a screenshot using Chrome DevTools:
There are 3 Capture... commands in Chrome DevTools. Just follow these steps to get to them:
Open DevTools.
Go to the Elements tab and click on the element you want to take the screenshot of.
Press Cmd + P on Mac or Ctrl + P on Windows.
Type > screen. You will get 3 relevant suggestions:
Mobile Capture full size screenshot: Captures the whole page, including the non-visible (out of viewport) area.
Mobile Capture node screenshot: Captures a single node, in this case, the element you clicked in the second step.
Mobile Capture screenshot: Captures the visible area of the page (viewport).
Click on any of them and the screenshot will download automatically.
However, keep in mind this feature doesn't always work fine, especially the Capture node screenshot one, so it might be better to capture the visible area of the page and crop the afterwards.
I made a crop screenshot and upload addon for Firefox. I would like to bring a feature that allows user to tweet the images.
Manually (as human does it) the process is this:
Open twitter.com (if not signed in tell user to sign in)
Click "new tweet" this is done
Attach images by doing "Add photo" and browse to file
This is gif of this process:
Then I focus the tab and focus the tweet input box
So user can type the message, then "whose in the photos" if they want, then click tweet. The great thing is with this method, the images have not bothered twitter servers, as the images are not uploaded until users final write off, when they click the "Tweet" button. So user has chance to decide to click X to remove a screenshot attached before hitting "Tweet". I find this way very friendly to the user and to the twitter servers. (If there is a file size limit that can be attached ill do that check in my addon and let user know it cant go in)
The problem
I am trying to automate steps 1-4. I can do 1, 2, and 4 perfectly.
I am trying to programmatically do step 3. It seems Twitter does not use the input[type=file].files html5 api, they are doing some custom javascript. Does anyone know how I can programtically add in images? I have full privelaged javascirpt code access as this is a Firefox addon.
One big reason I cant tell user to go attach themslves is these image are stored in memory for performance, not in file, so I need to attach them programtically.
Code I tried (HTML5 FileList API)
It uses the mozSetFileArray defined here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement and its brother mozSetFileNameArray here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/mozSetFileNameArray
// Step 1 - Open twitter.com (for testing purposes, twitter.com is open in tab 7 so I dont load it here)
var aContentWindow = gBrowser.tabContainer.childNodes[6].linkedBrowser.contentWindow; // gets window of tab 7
var aContentDocument = aContentWindow.document;
// Step 2 - Open tweet modal
var btnNewTweet = aContentDocument.getElementById('global-new-tweet-button');
console.info('btnNewTweet:', btnNewTweet);
if (!btnNewTweet) {
throw new Error('global tweet button not found, probably not logged in');
}
btnNewTweet.click();
// Step 3 - Attach two File instances for test purposes (in production will attach Blob)
var inputAddPhoto = aContentDocument.getElementById('global-tweet-dialog').querySelector('input[type=file]');
console.info('inputAddPhoto:', inputAddPhoto, inputAddPhoto.mozGetFileNameArray);
if (!inputAddPhoto) {
throw new Error('add photo button not found! i have no idea what could cause this');
}
var newFiles = [];
var myFile1 = new File('C:\\Users\\Vayeate\\Pictures\\Screenshot - Tuesday, August 11, 2015 6-33-58 AM.png'); // using local file for testing
var myFile2 = new File('C:\\Users\\Vayeate\\Pictures\\Screenshot - Tuesday, August 11, 2015 6-38-08 AM.png'); // using local file for testing
newFiles.push(myFile1);
newFiles.push(myFile2);
inputAddPhoto.mozSetFileArray(newFiles);
// Step 4 - Focus message field
// var richInputTweetMsg = aContentDocument.getElementById('tweet-box-global');
// richInputTweetMsg.focus(); // not needed because as when the modal opens twitter puts focus into here anways
// Step 5 - Done, now user can choose to type message, tag "whose in photo", and remove previews. The great thing is with this method, the images have not bothered twitter servers, the images are not uploaded until users final write off, when they click the "Tweet" button
Inspection
I did some debugger inspection, I put a breakpoint on drop, and found that it comes in here, there's some kind of add function.
I just started to develop with xCode because i need a WebView container for a website.
It works so far but i can't logout on the website because there is (in a web browser) a popup window asking if i was sure to logout. I guess it is creates with javascript.
In the Web View settings there is a checkbox labeled "allow popups" but in my app no popup appears after the click.
I've searched for two hours and didn't find something similar related to my problem.
It was a confirm() function of javascript.
I got it to work with:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[webView setUIDelegate:self]; // <------- This is an important part!!!
[[webView preferences] setJavaScriptEnabled:YES];
[[webView preferences] setJavaScriptCanOpenWindowsAutomatically:YES];
[[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:homeURLString]]];
}
and
- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame {
NSInteger result = NSRunInformationalAlertPanel(NSLocalizedString(#"JavaScript", #""), // title
message, // message
NSLocalizedString(#"OK", #""), // default button
NSLocalizedString(#"Cancel", #""), // alt button
nil);
return NSAlertDefaultReturn == result;
}
More Info here and here.
I have a website which has all pages contents in one page called "pagecontents". When a menu in navbar is clicked the jQuery load function is triggered and the relevant content is loaded into the main page.
It's working fine, however I added an hash to the URL for whenever a particular content is loaded , so that users can go directly into viewing relevant content when they type or paste the url with the hash. This works fine in my local host but not on remote host I wonder What's the problem.
if(location.hash == '#web') {
$('#contentFetch').load('pagecontents.php #webC');
}if(location.hash == '#graphic') {
$('#contentFetch').load('pagecontents.php #graphicC');
}if(location.hash == '#mobile') {
//$('#testLocation').text("mobile Works");
$('#contentFetch').load('pagecontents.php #mobileC');
}if(location.hash == '#contact') {
$('#contentFetch').load('pagecontents.php #contactC');
}else{
$('#contentFetch').load('pagecontents.php #indexC');
}
Edit: About the hash in query string:
the website url ex: 'www.mywebsite.com/'. when i add the '#graphic' at the end: 'www.mywebsite.com/#graphic' it's not loading the content. I noticed that if keep on pressing enter even though is not loading, it then loads!!!? it seems very incosistent as it loads 1 time out of 5. I wonder if using this is reliable in real world, or is there another way of doing it? Thanks, Mike
Make sure to check the runtime versions that your host is using and that they comply with the ones you have locally.
Usually, a host will run a version of a software that is often outdated in order to accommodate older websites. (ex. running PHP 4 instead of PHP 5).
I'm working with MVC3 and Bootstrap Responsive, and I want to detect by Razor (or javascript) which mode is active (desktop, tablet or phone) to show the correct partial view in one case or another.
For example:
#if( mode=='phone')
{
#html.Partial("_partialPhone")
}
#if( mode=='desktop')
{
#html.Partial("_partialDesktop")
}
...etc
I don't want to use just ".visible-phone" "visible-tablet" and ".visible-desktop" css classes, because although only one partial view is displayed, all of them are loaded in the DOM and rendered by Razor engine. And that is not good for a Phone and Tablet performance.
Can anyone help me?
Thanks
Media queries happen on the client.
This is fundamentally impossible.
You could have the client set its size in a cookie, then read the cookie on the server.
You should be able to do that with MVC4 (I don't know if this functionality exists in MVC3, but the sample on the site below uses MVC4 so that's what I'm basing my response on).
Switchable Mobile Views
It appears that you can start making files named like [ActionName].Mobile.cshtml and ASP.NET automatically uses those when it detects a request from a mobile device (and this appears to be customizable so you could create your own for tablets or whatever). He demonstrates something similar to what you are asking about in Razor - he renders different links based on the current display mode, but I assume this would work to render different partial views as well:
#if (Request.Browser.IsMobileDevice && Request.HttpMethod == "GET")
{
<div class="view-switcher ui-bar-a">
#if (ViewContext.HttpContext.GetOverriddenBrowser().IsMobileDevice)
{
#: Displaying mobile view
#Html.ActionLink("Desktop view", "SwitchView", "ViewSwitcher", new { mobile = false, returnUrl = Request.Url.PathAndQuery }, new { rel = "external" })
}
else
{
#: Displaying desktop view
#Html.ActionLink("Mobile view", "SwitchView", "ViewSwitcher", new { mobile = true, returnUrl = Request.Url.PathAndQuery }, new { rel = "external" })
}
</div>
}
Though if you have separate mobile views and desktop views then it I wouldn't think you'd need to manually switch between the two partials like you are asking about.
Related information